SkillByAIOpen interactive version →

Lesson 8 / 26

Error Handling

HTTPException and custom handlers.

Map domain errors to responses

Raise HTTPException(status_code, detail) for simple cases. For domain errors (out of stock, payment declined), define exception classes and register exception handlers that convert them to consistent JSON responses with the right status (409 Conflict, 402, 404). Keep error bodies stable for clients, log unexpected exceptions with context, and never return stack traces.

Errors, tests, data

Consistent errors, overridable dependencies for tests, and a database layer complete a FastAPI service.

Figure 3.1 — Errors, tests and data.

A domain exception mapped to 409, run

I ran this with Python 3.12, FastAPI 0.142.2, Pydantic 2.13 and Starlette 1.7, calling the app through FastAPI's TestClient (no server needed). A normal order succeeds; OutOfStock is converted by its handler into a 409 response; an unknown item raises HTTPException 404.

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient

class OutOfStock(Exception):
    def __init__(self, item: str):
        self.item = item

app = FastAPI()

@app.exception_handler(OutOfStock)
async def out_of_stock_handler(request: Request, exc: OutOfStock):
    return JSONResponse(status_code=409, content={"error": "out_of_stock", "item": exc.item})

@app.post("/orders/{item}")
def order(item: str):
    if item == "lamp":
        raise OutOfStock(item)
    if item not in {"pen", "ink"}:
        raise HTTPException(status_code=404, detail=f"Unknown item {item}")
    return {"ordered": item}

client = TestClient(app)
for item in ["pen", "lamp", "rocket"]:
    r = client.post(f"/orders/{item}")
    print(r.status_code, r.json())

Output:

200 {'ordered': 'pen'}
409 {'error': 'out_of_stock', 'item': 'lamp'}
404 {'detail': 'Unknown item rocket'}

Use a consistent error shape

Pick one error format (for example RFC 9457 problem details) for all endpoints so clients handle errors uniformly.

Quick check: Which status fits "item is out of stock" for an order request?

  • 500 Internal Server Error
  • 200 OK
  • 409 Conflict
  • 301 Moved Permanently
Answer

409 Conflict — The request conflicts with current state.