Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

Follow publication

Error and Exception Handling in FastAPI

Joël-Steve N.
Stackademic
Published in
4 min readJul 2, 2024

Handling errors and exceptions effectively is crucial in building robust and user-friendly APIs. FastAPI provides a powerful and flexible system for managing and customizing error responses. In this article, we will explore various techniques for handling and customizing errors in FastAPI, with practical code examples.

1. Basic Error Handling in FastAPI

FastAPI has built-in support for handling common HTTP errors. For example, if a required query parameter is missing, FastAPI will automatically return a 422 Unprocessable Entity response.

Example: Handling Missing Query Parameters

from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: str = Query(...)):
return {"q": q}

If you access /items/ without the q parameter, FastAPI returns a 422 status code with a detailed error message.

2. Customizing Error Responses

You can customize error responses by using exception handlers. FastAPI allows you to define handlers for specific exceptions, which can then return custom responses.

Example: Custom Exception Handler

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse

app = FastAPI()

class ItemNotFoundException(Exception):
def __init__(self, item_id: int):
self.item_id = item_id

@app.exception_handler(ItemNotFoundException)
async def item_not_found_exception_handler(request: Request, exc: ItemNotFoundException):
return JSONResponse(
status_code=404,
content={"message": f"Item with id {exc.item_id} not found"},
)

@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id != 1:
raise ItemNotFoundException(item_id=item_id)
return {"item_id": item_id}

When an ItemNotFoundException is raised, FastAPI will use the custom exception handler to return a 404 response with a custom error message.

3. Handling Validation Errors

FastAPI uses Pydantic for data validation and provides detailed error messages out of the box. You can customize the response for validation errors using the RequestValidationError exception handler.

Example: Custom Validation Error Handler

from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

app = FastAPI()

@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},
)

@app.post("/items/")
async def create_item(name: str):
if not name:
raise RequestValidationError([{"loc": ["body", "name"], "msg": "Name is required", "type": "value_error"}])
return {"name": name}

This handler customizes the validation error response to include the validation errors and the request body.

4. Global Exception Handling

You can create a global exception handler to catch all unhandled exceptions and return a standardized response. This is useful for logging errors and ensuring that the API always returns a consistent error format.

Example: Global Exception Handler

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging

app = FastAPI()

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
logging.error(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Internal Server Error"},
)

@app.get("/cause_error")
async def cause_error():
raise Exception("This is an unhandled exception")

This global handler logs the exception and returns a 500 Internal Server Error response.

5. Using HTTPException for Custom Error Responses

The HTTPException class can be used to raise HTTP errors with custom status codes and detail messages. This is useful for handling specific error cases within your endpoints.

Example: Using HTTPException

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id == 0:
raise HTTPException(status_code=400, detail="Invalid item ID")
return {"item_id": item_id}

In this example, if the item_id is 0, a 400 Bad Request error is raised with a custom detail message.

6. Dependency Injection for Error Handling

You can use FastAPI’s dependency injection system to handle errors that occur within dependencies.

Example: Dependency Error Handling

from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse

app = FastAPI()

class DependencyError(Exception):
pass

async def dependency_function():
raise DependencyError("Dependency failed")

@app.exception_handler(DependencyError)
async def dependency_exception_handler(request: Request, exc: DependencyError):
return JSONResponse(
status_code=500,
content={"message": str(exc)},
)

@app.get("/items/")
async def read_items(dep: str = Depends(dependency_function)):
return {"message": "Success"}

In this case, if the dependency_function raises a DependencyError, the custom exception handler will handle it and return a 500 response.

Conclusion

Effective error and exception handling is essential for building reliable APIs. FastAPI provides robust tools for customizing error responses, handling validation errors, and managing exceptions globally or within specific dependencies. By using these techniques, you can ensure that your FastAPI application provides clear and consistent error messages, improving the overall user experience.

Stay updated on the latest FastAPI techniques and best practices! Subscribe to our newsletter for more insights, tips, and exclusive content.

Subscribe now and enhance your FastAPI projects!

Stackademic 🎓

Thank you for reading until the end. Before you go:

Published in Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

Written by Joël-Steve N.

Senior Back-End Developer (Python, JavaScript, Java) | Community Manager & Tech Leader

Responses (2)

Write a response

I have no idea how I missed app.exception_handler. Wow. Thank you for this.

--

This was awesome ! thanks for your great insights

--