python 34 lines · 7 steps

Custom exception handlers in FastAPI

Map a domain-specific exception to a structured HTTP error response so route handlers can fail by raising, not by formatting JSON.

Explained by highlit
1from fastapi import FastAPI, Request, status
2from fastapi.responses import JSONResponse
3 
4app = FastAPI()
5 
6 
7class InsufficientFundsError(Exception):
8 def __init__(self, account_id: str, balance: float, requested: float):
9 self.account_id = account_id
10 self.balance = balance
11 self.requested = requested
12 
13 
14@app.exception_handler(InsufficientFundsError)
15async def insufficient_funds_handler(request: Request, exc: InsufficientFundsError):
16 return JSONResponse(
17 status_code=status.HTTP_402_PAYMENT_REQUIRED,
18 content={
19 "error": "insufficient_funds",
20 "message": f"Account {exc.account_id} cannot withdraw {exc.requested:.2f}.",
21 "available_balance": exc.balance,
22 "shortfall": round(exc.requested - exc.balance, 2),
23 },
24 headers={"X-Error-Code": "INSUFFICIENT_FUNDS"},
25 )
26 
27 
28@app.post("/accounts/{account_id}/withdraw")
29async def withdraw(account_id: str, amount: float):
30 account = await accounts.get(account_id)
31 if amount > account.balance:
32 raise InsufficientFundsError(account_id, account.balance, amount)
33 await account.debit(amount)
34 return {"account_id": account_id, "balance": account.balance - amount}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Centralizing error formatting in a handler keeps route logic focused on the happy path.
  2. 2A custom exception can carry rich context that the handler turns into a meaningful response.
  3. 3Mapping domain failures to specific status codes makes an API's errors predictable for clients.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Custom exception handlers in FastAPI — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code