---
title: "Errors"
description: ""
icon: "circle-exclamation"
---

## Overview

Error handling is a critical part of any Python application, especially when dealing with asynchronous operations, various error types, and error propagation across multiple layers. In the BeeAI Framework, we provide a robust and consistent error-handling structure that ensures reliability and ease of debugging.

<Note>
Supported in Python and TypeScript.
</Note>

---

## The FrameworkError class

Within the BeeAI Framework, regular Python Exceptions are used to handle common issues such as `ValueError`, `TypeError`. However, to provide a more comprehensive error handling experience, we have introduced `FrameworkError`, which is a subclass of Exception. Where additional context is needed, we can use `FrameworkError` to provide additional information about the nature of the error. This may wrap the original exception following the standard Python approach.

Benefits of using `FrameworkError`:

- **Additional properties**: Exceptions may include additional properties to provide a more detailed view of the error.
- **Preserved error chains**: Retains the full history of errors, giving developers full context for debugging.
- **Context**: Each error can contain a dictionary of context, allowing you to store additional values to help the user identify and debug the error.
- **Utility functions:** Includes methods for formatting error stack traces and explanations, making them suitable for use with LLMs and other external tools.
- **Native support:** Built on native Python Exceptions functionality, avoiding the need for additional dependencies while leveraging familiar mechanisms.

This structure ensures that users can trace the complete error history while clearly identifying any errors originating from the BeeAI Framework.

<CodeGroup>

{/* <!-- embedme python/examples/errors/base.py --> */}
```py Python [expandable]
from beeai_framework.errors import FrameworkError

# Create the main FrameworkError instance
error = FrameworkError("Function 'getUser' has failed.", is_fatal=True, is_retryable=False)
inner_error = FrameworkError("Cannot retrieve data from the API.")
innermost_error = ValueError("User with Given ID Does not exist!")

# Chain the errors together using __cause__
inner_error.__cause__ = innermost_error
error.__cause__ = inner_error

# Set the context dictionary for the top level error
# Add any additional context here. This will help with debugging
error.context["workflow"] = "activity_planner"
error.context["provider"] = "ollama"
error.context["chat_model"] = "granite3.2:8b"

# Print some properties of the error
print("\n-- Error properties:")
print(f"Message: {error.message}")  # Main error message
# Is the error fatal/retryable?
print(f"Meta: fatal:{FrameworkError.is_fatal(error)} retryable:{FrameworkError.is_retryable(error)}")
print(f"Cause: {error.get_cause()}")  # Prints the cause of the error
print(f"Context: {error.context}")  # Prints the dictionary of the error context

print("\n-- Explain:")
print(error.explain())  # Human-readable format without stack traces (ideal for LLMs)
print("\n-- str():")
print(str(error))  # Human-readable format (for debug)

```

{/* <!-- embedme typescript/examples/errors/base.ts --> */}
```ts TypeScript [expandable]
import { FrameworkError } from "beeai-framework/errors";

const error = new FrameworkError(
  "Function 'getUser' has failed.",
  [
    new FrameworkError("Cannot retrieve data from the API.", [
      new Error("User with given ID does not exist!"),
    ]),
  ],
  {
    context: { input: { id: "123" } },
    isFatal: true,
    isRetryable: false,
  },
);

console.log("Message", error.message); // Main error message
console.log("Meta", { fatal: error.isFatal, retryable: error.isRetryable }); // Is the error fatal/retryable?
console.log("Context", error.context); // Context in which the error occurred
console.log(error.explain()); // Human-readable format without stack traces (ideal for LLMs)
console.log(error.dump()); // Full error dump, including sub-errors
console.log(error.getCause()); // Retrieve the initial cause of the error

```
</CodeGroup>

Framework error also has two additional properties which help with agent processing, though ultimately the code that catches the exception will determine the appropriate action.

- **is_retryable** : hints that the error is retryable.
- **is_fatal** : hints that the error is fatal.

### Specialized error classes

The BeeAI Framework extends `FrameworkError` to create specialized error classes for different components or scenarios. This ensures that each part of the framework has clear and well-defined error types, improving debugging and error handling.

<Tip>
Casting an unknown error to a `FrameworkError` can be done by calling the `FrameworkError.ensure` static method ([Python example](https://github.com/i-am-bee/beeai-framework/blob/main/python/examples/errors/cast.py), [TypeScript example](https://github.com/i-am-bee/beeai-framework/blob/main/typescript/examples/errors/cast.ts)).
</Tip>

The definitions for these classes are typically local to the module where they are raised.

| Error Class | Category | Description |
| :------------- | :---------- | :-------------|
| `AbortError` | Aborts | Raised when an operation has been aborted |
| `ToolError` | Tools | Raised when a problem is reported by a tool |
| `ToolInputValidationError` | Tools | Extends ToolError, raised when input validation fails |
| `AgentError` | Agents | Raised when problems occur in agents |
| `PromptTemplateError` | Prompt Templates | Raised when problems occur processing prompt templates |
| `LoggerError` | Loggers | Raised when errors occur during logging |
| `SerializerError` | Serializers | Raised when problems occur serializing or deserializing objects |
| `WorkflowError` | Workflow | Raised when a workflow encounters an error |
| `ParserError` | Parser | Raised when a parser fails to parse the input data. Includes additional *Reason* |
| `ResourceError` | Memory | Raised when an error occurs with processing agent memory |
| `ResourceFatalError` | Memory | Extends ResourceError, raised for particularly severe errors that are likely to be fatal |
| `EmitterError` | Emitter | Raised when a problem occurs in the emitter |
| `BackendError` | Backend | Raised when a backend encounters an error |
| `ChatModelError` | Backend | Extends BackendError, raised when a chat model fails to process input data |
| `MessageError` | Backend | Raised when a message processing fails |

## Tools example

<CodeGroup>

{/* <!-- embedme python/examples/errors/tool.py --> */}
```py Python [expandable]
import asyncio

from beeai_framework.tools import ToolError, tool


async def main() -> None:
    @tool
    def dummy() -> None:
        """
        A dummy tool.
        """
        raise ToolError("Dummy error.")

    await dummy.run({})


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except ToolError as e:
        print("===CAUSE===")
        print(e.get_cause())
        print("===EXPLAIN===")
        print(e.explain())

```

{/* <!-- embedme typescript/examples/errors/tool.ts --> */}
```ts TypeScript [expandable]
import { DynamicTool, ToolError } from "beeai-framework/tools/base";
import { FrameworkError } from "beeai-framework/errors";
import { z } from "zod";

const tool = new DynamicTool({
  name: "dummy",
  description: "dummy",
  inputSchema: z.object({}),
  handler: async () => {
    throw new Error("Division has failed.");
  },
});

try {
  await tool.run({});
} catch (e) {
  const err = e as FrameworkError;
  console.log(e instanceof ToolError); // true
  console.log("===DUMP===");
  console.log(err.dump());

  console.log("===EXPLAIN===");
  console.log(err.explain());
}

```
</CodeGroup>

---

## Usage

### Basic usage

To use Framework error, add the following import:
```py Python [expandable]
from beeai_framework.errors import FrameworkError
```

Add any additional custom errors you need in your code to the import, for example
```py Python [expandable]
from beeai_framework.errors import FrameworkError, ChatModelError,ToolError
```

### Creating custom errors

If you wish to create additional errors, you can extend `FrameworkError` or any of the other errors above:

```py Python [expandable]
from beeai_framework.errors import FrameworkError

class MyCustomError(FrameworkError):
    def __init__(self, message: str = "My custom error", *, cause: Exception | None = None, context: dict | None = None) -> None:
        super().__init__(message, is_fatal=True, is_retryable=False, cause=cause, context=context)
```

### Wrapping existing errors

You can wrap existing errors in a `FrameworkError`, for example:
```py Python [expandable]
inner_err: Exception = ValueError("Value error")
error = FrameworkError.ensure(inner_err)
raise(error)
```

### Using properties and methods

Framework error also has two additional properties which help with agent processing, though ultimately the code that catches the exception will determine the appropriate action.

- **is_retryable** : hints that the error is retryable.
- **is_fatal** : hints that the error is fatal.

These can be accessed via:

```py Python [expandable]
err = FrameworkError("error")
isfatal: bool = FrameworkError.is_fatal(err)
isretryable: bool = FrameworkError.is_retryable(err)
```

This allows use of some useful functions within the error class.

For example the `explain` static method will return a string that may be more useful for an LLM to interpret:

```py Python [expandable]
message: str = FrameworkError.ensure(error).explain()
```

See the source file [errors.py](https://github.com/i-am-bee/beeai-framework/blob/main/python/beeai_framework/errors.py) for additional methods.

## Examples

<CardGroup cols={2}>
  <Card title="Python" icon="python" href="https://github.com/i-am-bee/beeai-framework/tree/main/python/examples/errors">
    Explore reference error implementations in Python
  </Card>
  <Card title="TypeScript" icon="js" href="https://github.com/i-am-bee/beeai-framework/tree/main/typescript/examples/errors">
    Explore reference error implementations in TypeScript
  </Card>
</CardGroup>
