FastAPI has add_exception_handler(...)
for global error handling, and it works — until the same exception needs different meanings depending on context: 404 in one route, 401 in another, 422 elsewhere. Global handlers don’t account for that, and the behavior isn’t visible on the route itself.
Local try/except
or decorators help, but try/except
duplicates logic, and decorators don’t expose possible responses to FastAPI — so they’re missing from OpenAPI. Manual responses={...}
can drift from actual behavior.
📦 fastapi-error-map lets you declare error handling right in the route via error_map
, and generates the OpenAPI schema from those declarations.
Basic usage
Import ErrorAwareRouter
instead of APIRouter
, and define error handling rules per endpoint.
router = ErrorAwareRouter()
@router.get(
"/stock",
error_map={
# Just return 401 with default JSON
# like {"error": "..."}
AuthorizationError: 401,
# Return 409 with custom response,
# and run a side effect (e.g. notify)
OutOfStockError: rule(
status=409,
translator=OutOfStockTranslator(),
on_error=notify,
),
},
)
def check_stock(user_id: int = 0) -> None:
if user_id == 0:
raise AuthorizationError
raise OutOfStockError("No items available.")
OpenAPI picks these responses up automatically from error_map
:
Key features
- 🔄 Drop-in compatibility with
APIRouter
— just replace and keep working. - 📜 Automatic OpenAPI generation from
error_map
— no manualresponses={...}
and no risk of drift. - 🛠 Custom rules via
rule(...)
— define status, translator, and callback per exception. - ⚡ Error callbacks with
on_error
— trigger logging, alerts, metrics, or any side effect before responding. - 🎯 Exact error type matching (no inheritance) — explicit and predictable behavior.
- 🚨 Strict mode: warns if an exception isn’t mapped (
warn_on_unmapped=True
).
Install
pip install fastapi-error-map
Would love to hear what you think!
P.S. See it powering clean architecture example app:
👉 https://github.com/ivan-borovets/fastapi-clean-example