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

from fastapi import FastAPI, HTTPException

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 israiseinstead 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

ParameterTypeDescription
status_codeintHTTP status code (required)
detailAnyError details can be a string, dictionary, list, etc.
headersdict | NoneAdditional response headers (optional)

Custom error details

detailThe parameter can be of any type, not limited to strings:

Example

from fastapi import FastAPI, HTTPException

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

from fastapi import FastAPI, HTTPException

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 headersRetry-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 import FastAPI, Request
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 import FastAPI, Request
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 import FastAPI
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 import FastAPI
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

  • Usageraise 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.
  • UsageRedirectResponseImplement redirect
other extensions