# How Open Notebook Maps Provider Exceptions to HTTP Status Codes

> Understand how Open Notebook maps provider exceptions to HTTP status codes using FastAPI's exception handler to convert errors into standard codes like 429 and 502.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-29

---

**Open Notebook maps provider exceptions to HTTP codes using a centralized FastAPI exception handling layer in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) that converts custom errors from [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py) into standard status codes like 429 and 502.**

Open Notebook implements a robust translation layer that maps provider exceptions to HTTP codes, ensuring API clients receive semantic status codes when AI services fail. This architecture, found in the `lfnovo/open-notebook` repository, centralizes error handling logic at the FastAPI application level.

## Centralized Exception Architecture

### Custom Exception Definitions in [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py)

All provider-related exceptions inherit from a base `OpenNotebookError` class defined in [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py). The hierarchy includes specific error types for distinct failure modes encountered when communicating with external AI services.

### FastAPI Handler Registration in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py)

The FastAPI application registers exception handlers using the `@app.exception_handler` decorator. Each handler catches a specific exception type and returns a `JSONResponse` with the mapped status code and CORS headers applied via the internal `_cors_headers` helper function.

## Complete HTTP Status Code Mapping

The following mappings detail how Open Notebook translates specific provider failures into HTTP responses:

- **`RateLimitError`** → **429 Too Many Requests** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 44-50)
- **`NetworkError`** → **502 Bad Gateway** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 62-68)
- **`ExternalServiceError`** → **502 Bad Gateway** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 71-77)
- **`AuthenticationError`** → **401 Unauthorized** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 35-41)
- **`InvalidInputError`** → **400 Bad Request** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 26-32)
- **`NotFoundError`** → **404 Not Found** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 18-24)
- **`ConfigurationError`** → **422 Unprocessable Entity** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 48-54)
- **`OpenNotebookError`** (generic fallback) → **500 Internal Server Error** (Handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py), lines 80-86)

## Error Propagation Flow

### Provider Error Detection

When interacting with AI providers in modules like [`open_notebook/ai/model_discovery.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/model_discovery.py) or [`open_notebook/ai/connection_tester.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/connection_tester.py), the code detects specific failure conditions. For example, an HTTP 429 response from a provider triggers a `RateLimitError`, while connection timeouts raise `NetworkError`.

### Exception Bubbling to the API Layer

These custom exceptions propagate up the call stack to the FastAPI route handlers. While route functions may catch generic `OpenNotebookError` instances and re-raise them as standard `HTTPException` objects, specific custom exceptions are intentionally allowed to bubble up unchanged. This design lets FastAPI invoke the dedicated global handlers rather than wrapping the errors.

### Handler Execution and Response Formatting

When a handler executes, it constructs a `JSONResponse` object containing the exception message in a `detail` field. The handler also injects CORS headers using the internal `_cors_headers(request)` utility to ensure browser clients can read error responses across origins.

## Practical Code Examples

### Raising a Rate Limit Exception

```python
from open_notebook.exceptions import RateLimitError

def call_provider(...):
    response = httpx.get(url)
    if response.status_code == 429:
        raise RateLimitError("Provider rate limit exceeded")
    ...

```

### Handling Network Failures

```python
from open_notebook.exceptions import NetworkError

async def fetch_embeddings(...):
    try:
        await httpx.post(...)
    except httpx.RequestError as e:
        raise NetworkError(f"Network error contacting provider: {e}")

```

### FastAPI Handler Implementation

```python
@app.exception_handler(RateLimitError)
async def rate_limit_error_handler(request: Request, exc: RateLimitError):
    return JSONResponse(
        status_code=429,
        content={"detail": str(exc)},
        headers=_cors_headers(request),
    )

```

## Summary

- Open Notebook defines **custom exception classes** in [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py) for distinct provider failure modes such as rate limits, network errors, and authentication failures.
- **FastAPI exception handlers** in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) map each exception type to a specific, semantic HTTP status code using the `@app.exception_handler` decorator.
- Provider errors bubble up from `open_notebook/ai/*` modules to the API layer without re-wrapping, triggering the global handlers that return **standard HTTP status codes** (400, 401, 404, 422, 429, 502, 500).
- The system returns **JSON error payloads** with CORS headers applied, ensuring cross-origin clients can properly handle provider failures.

## Frequently Asked Questions

### What HTTP status code does Open Notebook return for AI rate limits?

Open Notebook returns **429 Too Many Requests** when the provider signals a rate limit. The `RateLimitError` exception defined in [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py) is caught by a dedicated handler in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 44-50) that returns this specific status code with a JSON detail message.

### How does Open Notebook handle network failures from providers?

Network timeouts and connection failures raise `NetworkError`, which maps to **502 Bad Gateway**. This indicates to API clients that the Open Notebook server received an invalid response or no response from the upstream AI provider, as implemented in the handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) lines 62-68.

### Where are the exception handlers registered in the Open Notebook codebase?

All exception handlers are registered in **[`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py)** using FastAPI's `@app.exception_handler` decorator. This file serves as the central registry that maps provider exceptions to HTTP codes, keeping error handling logic consistent across the entire API surface.

### What happens when an unrecognized provider error occurs?

Unhandled errors that inherit from `OpenNotebookError` but lack specific handlers return **500 Internal Server Error** via the fallback handler at [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) lines 80-86. This generic mapping ensures internal provider failures do not leak implementation details while still indicating server-side failure to the client.