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.