How Open Notebook Maps Provider Exceptions to HTTP Status Codes

Open Notebook maps provider exceptions to HTTP codes using a centralized FastAPI exception handling layer in api/main.py that converts custom errors from 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

All provider-related exceptions inherit from a base OpenNotebookError class defined in 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

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:

  • RateLimitError429 Too Many Requests (Handler at api/main.py, lines 44-50)
  • NetworkError502 Bad Gateway (Handler at api/main.py, lines 62-68)
  • ExternalServiceError502 Bad Gateway (Handler at api/main.py, lines 71-77)
  • AuthenticationError401 Unauthorized (Handler at api/main.py, lines 35-41)
  • InvalidInputError400 Bad Request (Handler at api/main.py, lines 26-32)
  • NotFoundError404 Not Found (Handler at api/main.py, lines 18-24)
  • ConfigurationError422 Unprocessable Entity (Handler at api/main.py, lines 48-54)
  • OpenNotebookError (generic fallback) → 500 Internal Server Error (Handler at 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 or 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

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

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

@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 for distinct provider failure modes such as rate limits, network errors, and authentication failures.
  • FastAPI exception handlers in 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 is caught by a dedicated handler in 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 lines 62-68.

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

All exception handlers are registered in 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 lines 80-86. This generic mapping ensures internal provider failures do not leak implementation details while still indicating server-side failure to the client.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →