Skip to main content

Overview of FastAPI Exceptions

FastAPI provides a structured exception hierarchy in fastapi/exceptions.py designed to distinguish between internal framework issues, data validation failures, and intentional client-facing errors.

Internal Framework Errors​

The FastAPIError class is the base for all exceptions that indicate a problem within the FastAPI framework's operation or configuration. Unlike standard HTTP errors, these inherit from Python's built-in RuntimeError and are typically not meant to be caught by application logic, as they often signal a developer error or a configuration mismatch.

Core Framework Exceptions​

  • FastAPIError: The generic base class. It is raised in scenarios where the framework's internal state becomes inconsistent. For example, in fastapi/routing.py, it is raised if a response is not properly awaited due to improper exception handling in a dependency with yield:
    if not response_awaited:
    raise FastAPIError(
    "Response not awaited. There's a high chance that the "
    "application code is raising an exception and a dependency with yield "
    "has a block with a bare except..."
    )
  • DependencyScopeError: Raised when there is an invalid dependency resolution, such as a dependency attempting to use a narrower scope than its parent.
  • PydanticV1NotSupportedError: Raised when a Pydantic V1 model is used in a context where the framework requires V2, ensuring compatibility standards are met.

Validation Exceptions​

FastAPI uses a specialized hierarchy for validation errors, all inheriting from ValidationException. These exceptions are unique because they capture the context of where the validation failed within the application's code.

The Validation Hierarchy​

  • ValidationException: The base class that stores a sequence of errors and an EndpointContext. The EndpointContext (a TypedDict) includes the function name, file path, and line number of the failing endpoint.
  • RequestValidationError: Raised when client-provided data (body, query parameters, etc.) fails to match the defined Pydantic models or type hints. It includes a body attribute containing the original data that failed validation.
  • ResponseValidationError: Raised when the data returned by a path operation function does not match the declared response_model. This typically results in a 500 Internal Server Error because it indicates a bug in the server-side logic.

Debugging with Endpoint Context​

The ValidationException class implements a _format_endpoint_context method that helps developers locate the source of the error in their logs:

# From fastapi/exceptions.py
def _format_endpoint_context(self) -> str:
if not (self.endpoint_file and self.endpoint_line and self.endpoint_function):
if self.endpoint_path:
return f"\n Endpoint: {self.endpoint_path}"
return ""

context = f'\n File "{self.endpoint_file}", line {self.endpoint_line}, in {self.endpoint_function}'
if self.endpoint_path:
context += f"\n {self.endpoint_path}"
return context

Client-Facing Exceptions​

For communicating errors back to the client, FastAPI extends Starlette's exception classes. These are designed to be raised directly within path operations or dependencies.

HTTPException​

fastapi.exceptions.HTTPException inherits from starlette.exceptions.HTTPException. It allows you to return specific HTTP status codes and detailed error messages.

from fastapi import HTTPException

@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")

WebSocketException​

Similarly, WebSocketException inherits from starlette.exceptions.WebSocketException and is used to close WebSocket connections with specific codes and reasons.

from fastapi import WebSocketException, status

if session is None:
raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)

Customizing Exception Responses​

FastAPI allows you to override the default behavior for these exceptions using exception handlers. A common pattern is to catch RequestValidationError to provide more detailed feedback about which part of the request body failed.

In docs_src/handling_errors/tutorial005_py310.py, the framework demonstrates how to access the body attribute of the validation error:

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
)

This integration ensures that while ValidationException provides the internal context for debugging, the developer retains full control over the final response sent to the user.