FastAPI Error Handling
In API development, it is necessary to return error information to the client. FastAPI providesHTTPExceptionto raise HTTP errors, and also supports custom exception handlers to handle more complex error scenarios.
Use HTTPException
When you need to return an error response, raiseHTTPException:
Example
app = FastAPI()
items = {"foo": "The Foo Wrestlers", "bar": "The Bar Fighters"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
# When the resource does not exist, raise a 404 error
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
Visithttp://127.0.0.1:8000/items/42When, return:
{
"detail": "Item not found"
}
The HTTP status code is404。
Note that what is used here is
raiseinstead ofreturn。HTTPExceptionis an exception. After it is raised, FastAPI catches it and returns the corresponding HTTP error response. This is consistent with Python's exception handling mechanism.
HTTPException Parameters
| Parameter | Type | Description |
|---|---|---|
status_code | int | HTTP status code (required) |
detail | Any | Error details can be a string, dictionary, list, etc. |
headers | dict | None | Additional response headers (optional) |
Custom error details
detailThe parameter can be of any type, not limited to strings:
Example
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id == "invalid":
# detail can be a dict containing more error information
raise HTTPException(
status_code=400,
detail={
"error_code": "INVALID_ID",
"message": "Product ID format is incorrect",
"hint": "Please use an alphanumeric ID"
}
)
return {"item_id": item_id}
Add custom response headers
In some scenarios, you need to add custom response headers to the error response:
Example
app = FastAPI()
@app.get("/items-header/{item_id}")
async def read_item_header(item_id: str):
if item_id == "invalid":
raise HTTPException(
status_code=404,
detail="Item not found",
headers={"X-Error": "There goes my error"}, # Custom response headers
)
return {"item": item_id}
In scenarios where you need to limit client request frequency (rate limiting), you can add to the error response headers
Retry-Afterheader, telling the client when it can retry.
Custom exception handler
You can register handlers for custom exceptions or built-in exceptions to uniformly handle the error response format:
Example
from fastapi.responses import JSONResponse
# Custom exception class
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
app = FastAPI()
# Register exception handler
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
# Return a custom-format error response
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something wrong"},
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
# Raise custom exception
raise UnicornException(name=name)
return {"unicorn_name": name}
Override the default exception handler
FastAPI has default exception handlers. You can override them to customize the error response format:
Example
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
# Override HTTP exception handler
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
return JSONResponse(
status_code=exc.status_code,
content={"error": f"HTTP error: {exc.detail}"},
)
# Override request validation exception handler
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=422,
content={"error": "Data validation failed", "details": exc.errors()},
)
RequestValidationErroris an exception thrown by FastAPI when request data validation fails. Overriding its handler allows customizing the response format for validation errors.
Redirect
UsageRedirectResponseImplement redirection:
Example
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/items/")
async def read_items():
return {"items": ["foo", "bar"]}
@app.get("/redirect")
async def redirect():
# Redirect to /items/
return RedirectResponse(url="/items/")
Custom response headers and status code
UsageJSONResponseCustom response headers and status code:
Example
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
content = {"item_id": item_id}
headers = {"X-Custom-Header": "custom-header-value"}
return JSONResponse(content=content, headers=headers)
Summary
- Usage
raise HTTPExceptionReturn an HTTP error response detailThe parameter can be of any type (string, dictionary, list, etc.)- Usage
@app.exception_handlerRegister custom exception handler - You can override FastAPI's default exception handlers to unify the error format.
- Usage
RedirectResponseImplement redirect