# Error Handling โ€” Fail Loud, Fail Early `openapi-first` treats errors as **first-class contract documents**: every failure mode is a named exception with a stable import pathhare, and every one surfaces as early as possible. --- ## ๐Ÿงฌ 1. The Hierarchy All errors derive from `OpenAPIFirstError` (in `openapi_first/errors.py`), so a single `except OpenAPIFirstError` catches every first-party failure: ```text OpenAPIFirstError โ”œโ”€โ”€ OpenAPISpecError # spec-level problems โ”‚ โ””โ”€โ”€ OpenAPISpecLoadError # load / parse / validation (loader) โ”œโ”€โ”€ OpenAPIClientError # client-side contract issues (client) โ””โ”€โ”€ MissingOperationHandler # spec op with no handler (binder) # Security / loader layers raise through OpenAPISpecError subclasses too ``` | Exception | Module | Raised when | |----------------------------------|-----------|-------------| | `OpenAPISpecLoadError` | `loader` | Path missing, file unreadable, YAML/JSON invalid, or spec fails OpenAPI 3.x validation | | `OpenAPIClientError` | `client` | No `servers`, no `paths`, missing/duplicate `operationId`, missing required params at construction | | `MissingOperationHandler` | `errors` | An operation is declared whose `operationId` has no matching handler in `routes_module` | --- ## โฑ๏ธ 2. When Things Fail The single most important rule: **violations are eager, not lazy.** ### 2.1 At application startup ```python # openapi.yaml missing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ OpenAPISpecLoadError # operationId without a handler โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ MissingOperationHandler # operation with no operationId declared โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ MissingOperationHandler ``` Because these raise during `OpenAPIFirstApp(...)` construction, CI catches them the moment a spec and its routes drift โ€” before a single request is served. ### 2.2 At client construction ```python OpenAPIClient(spec) # fails fast, same philosophy ``` - Spec with no `servers` โ†’ `OpenAPIClientError` - Spec with no `paths` โ†’ `OpenAPIClientError` - Duplicate `operationId`s โ†’ `OpenAPIClientError` (client methods must be unambiguous) - Operation missing `operationId` โ†’ `OpenAPIClientError` ### 2.3 At call time (client) Runtime transport errors surface as `httpx` exceptions (`httpx.RequestError` family), not swallowed or remapped. Missing required args fail before any HTTP request is made: ```python client.get_user(path_params={"user_id": ...}) # OK client.get_user() # ValueError โ€” user_id required ``` --- ## ๐Ÿงฐ 3. Handling in Your App ### 3.1 Server-side Handlers raise FastAPI `HTTPException` for expected operation-level failures (404/422), and the `OperationId`-binding errors only exist at startup: ```python from fastapi import HTTPException def get_item(item_id: int): """Retrieve an item by ID. Implements the OpenAPI operation ``get_item``. Args: item_id (int): Identifier of the item. Raises: HTTPException: If the item does not exist (404). """ try: return _get_item(item_id) except KeyError: raise HTTPException(status_code=404, detail="Item not found") ``` ### 3.2 Client-side ```python import httpx try: response = client.get_item(path_params={"item_id": 1}) except httpx.HTTPStatusError as exc: ... # 4xx/5xx from the server ``` `httpx.HTTPStatusError` isn't raised by the library โ€” it's the standard `httpx.raise_for_status()` you can opt into per call. The library never masks a response code. --- ## ๐Ÿ›ก๏ธ 4. Fail-Fast Guarantees Recap | Layer | You write | The library guarantees | |-------|-----------|------------------------| | Loader | a spec path | unreadable/invalid specs never reach your app | | Binder | handler functions | every operation must resolve, or the app won't start | | Client | a spec | every operationId becomes a callable; missing ones fail at construction | | Runtime | handler code | FastAPI + Pydantic handle coercion; contract checks already happened at startup | None of these can silently degrade: a violation is an **exception at construction**, not a 500 at request time. --- ## Related - [01 โ€“ Overview](01_overview.md) ยท [05 โ€“ Security](05_security.md) ยท [07 โ€“ Testing](07_testing.md)