Core Exception Hierarchy
FastAPI provides a structured hierarchy of exceptions that distinguish between client-side errors, validation failures, and internal framework misconfigurations. While many of these exceptions inherit from Starlette or standard Python classes, FastAPI extends them to integrate with its dependency injection and Pydantic validation systems.
The Base Exception: FastAPIError
The FastAPIError class in fastapi/exceptions.py is the base for all internal framework errors. It inherits from Python's built-in RuntimeError.
class FastAPIError(RuntimeError):
"""
A generic, FastAPI-specific error.
"""
You generally do not raise this exception directly. Instead, you will encounter its subclasses when there is a logic error in how your application is structured. For example, DependencyScopeError is raised when a dependency with a broader scope (like a singleton) tries to depend on something with a narrower scope (like a request-scoped dependency).
Client-Facing Exceptions
When you need to stop the execution of a path operation and return an error to the client, you use HTTPException or WebSocketException.
HTTPException
FastAPI's HTTPException (in fastapi/exceptions.py) inherits from starlette.exceptions.HTTPException. It is designed to be raised anywhere in your code—inside path operations or dependencies—to immediately return a JSON response with a specific status code.
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
# Returns a 404 JSON response to the client
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
Internally, FastAPI provides a default handler http_exception_handler in fastapi/exception_handlers.py that converts this exception into a JSONResponse. It automatically includes the detail and any custom headers you provided.
WebSocketException
For WebSocket connections, use WebSocketException. It inherits from starlette.exceptions.WebSocketException and allows you to close a connection with a specific code and reason.
from fastapi import WebSocket, WebSocketException, status
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
# Close connection if some condition isn't met
raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION, reason="Policy violated")
Validation Exceptions
FastAPI uses a specialized hierarchy for validation errors, all inheriting from a base ValidationException. These exceptions capture an endpoint_ctx (of type EndpointContext), which includes the file, line number, and function name where the error occurred to assist in debugging.
RequestValidationError
When a client sends data that doesn't match your Pydantic models (in the body, query parameters, etc.), FastAPI raises a RequestValidationError.
By default, the request_validation_exception_handler in fastapi/exception_handlers.py catches this and returns a 422 Unprocessable Entity status code.
You can access the original request body that failed validation via the .body attribute:
from fastapi import Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=422,
content={"detail": exc.errors(), "body": exc.body},
)
ResponseValidationError
If your path operation returns data that does not match the defined response_model, FastAPI raises a ResponseValidationError.
Unlike request validation, this is considered a server-side error. Because there is no default handler that converts this to a specific client response, it bubbles up and results in a 500 Internal Server Error. This behavior ensures that invalid data (which might contain sensitive information not intended for the client) is not leaked when the server code is buggy.
Internal Logic Errors
Subclasses of FastAPIError indicate that the framework itself cannot proceed due to configuration issues:
- DependencyScopeError: Raised in
fastapi/dependencies/utils.pywhen there is a mismatch in dependency scopes. - PydanticV1NotSupportedError: Raised if you attempt to use Pydantic V1 models in versions of FastAPI that have deprecated or removed support for them.
These errors are meant for the developer during development and testing, rather than for the end-user.