> ## Documentation Index
> Fetch the complete documentation index at: https://daily-main.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Observer

> ErrorObserver reports every error a pipeline raises through on_error as an ErrorEvent with category, processor, and usability info.

The `ErrorObserver` reports each error a pipeline raises, once, where it is raised. It tracks both errors that surface and errors that are recovered from (e.g., a service switcher failing over).

## Features

* Reports every error at its origin
* Includes recovered errors that don't reach the top of the pipeline
* Provides error categorization via `ErrorCategory`
* Tracks processor usability after failures
* Deduplicates errors that travel through multiple processors

## Usage

### Basic Setup

```python theme={null}
from pipecat.observers.error_observer import ErrorObserver

observer = ErrorObserver()

@observer.event_handler("on_error")
async def on_error(observer, event):
    logger.error(
        f"Error in {event.processor}: {event.message} "
        f"(category: {event.category}, usable: {event.processor_usable})"
    )

worker = PipelineWorker(
    pipeline,
    observers=[observer],
)
```

### JSON Logging

Log errors as structured JSON:

```python theme={null}
@observer.event_handler("on_error")
async def on_error(observer, event):
    logger.info(event.model_dump_json())
```

## Configuration

<ParamField path="time_source" type="Callable[[], float]" default="time.time">
  Reads the current time in seconds. Supplying one lets a test place failures
  without waiting.
</ParamField>

## ErrorEvent

Each error is reported as an `ErrorEvent` with the following fields:

| Field              | Type            | Description                                                                      |
| ------------------ | --------------- | -------------------------------------------------------------------------------- |
| `message`          | `str`           | What went wrong, in the words of the processor that failed                       |
| `category`         | `ErrorCategory` | Why it failed (e.g., authentication, connectivity, server error)                 |
| `exception_type`   | `str \| None`   | The name of the exception behind the failure, useful for grouping similar errors |
| `processor`        | `str`           | The name of the processor that raised the error                                  |
| `processor_usable` | `bool`          | Whether the processor can still do its job; `False` means the capability is gone |
| `timestamp`        | `float`         | Unix timestamp of the failure                                                    |

## Event Handlers

| Event      | Handler Signature                      | Description                     |
| ---------- | -------------------------------------- | ------------------------------- |
| `on_error` | `async def on_error(observer, event):` | Emitted for each error reported |

## Notes

* Errors are reported once per occurrence, even though they travel upstream through multiple processors
* An error is attributed to the processor that raised it, not the ones that passed it along
* `processor_usable` distinguishes transient failures (unreachable service) from permanent ones (invalid credentials)
* Errors recovered by a processor (e.g., service switcher failover) are still reported, unlike `PipelineWorker.on_pipeline_error` which only sees errors that reach the top
