FastAPI Error Handling


What is error handling in FastAPI?

Error handling in FastAPI refers to the process of managing and responding to errors that occur during the execution of a request. FastAPI provides built-in mechanisms to handle different types of errors and exceptions, allowing you to return meaningful responses to the client with appropriate status codes and messages.


How does FastAPI handle exceptions by default?

FastAPI automatically handles exceptions and returns appropriate HTTP status codes for common errors. For example, if a route is not found, FastAPI returns a 404 Not Found response. If a validation error occurs, FastAPI returns a 422 Unprocessable Entity response with details about the validation issues.

Example of a 404 error:

GET /nonexistent-route
Response:
404 Not Found
{
  "detail": "Not Found"
}

In this example, FastAPI returns a 404 response for a route that does not exist.


How do you raise HTTP exceptions in FastAPI?

FastAPI provides the HTTPException class to manually raise HTTP errors in your route functions. This allows you to return custom error messages and status codes based on specific conditions.

Example of raising an HTTP exception:

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id != 1:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"item_id": item_id}

In this example, the read_item route raises an HTTPException with a 404 Not Found status code and a custom message when the item_id is not 1.


How do you handle validation errors in FastAPI?

FastAPI automatically handles validation errors using Pydantic. If the incoming data does not match the expected types or constraints, FastAPI returns a 422 Unprocessable Entity response with details about the validation errors.

Example of a validation error:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.post("/items/")
def create_item(item: Item):
    return item
POST /items/
{
  "name": "Item",
  "price": "invalid_price"  # Price should be a float, not a string
}

Response:
422 Unprocessable Entity
{
  "detail": [
    {
      "loc": ["body", "price"],
      "msg": "value is not a valid float",
      "type": "type_error.float"
    }
  ]
}

In this example, FastAPI returns a 422 error because the price field is not a valid float.


How do you create custom exception handlers in FastAPI?

FastAPI allows you to define custom exception handlers for specific exception types. You can use the @app.exception_handler() decorator to create custom handlers and control how exceptions are handled and returned to the client.

Example of a custom exception handler:

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

app = FastAPI()

class CustomException(Exception):
    def __init__(self, name: str):
        self.name = name

@app.exception_handler(CustomException)
def custom_exception_handler(request: Request, exc: CustomException):
    return JSONResponse(
        status_code=400,
        content={"message": f"Oops! {exc.name} caused an error."},
    )

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id != 1:
        raise CustomException(name="Invalid Item")
    return {"item_id": item_id}

In this example, a custom exception CustomException is raised, and a custom exception handler returns a specific error message to the client.


How do you handle global exceptions in FastAPI?

FastAPI allows you to handle global exceptions by defining a custom handler for the base Exception class. This will catch all unhandled exceptions and return a consistent response to the client.

Example of handling global exceptions:

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

app = FastAPI()

@app.exception_handler(Exception)
def global_exception_handler(request: Request, exc: Exception):
    return JSONResponse(
        status_code=500,
        content={"message": "An internal server error occurred."},
    )

@app.get("/cause-error/")
def cause_error():
    raise ValueError("This is an unhandled exception")

In this example, the global exception handler catches unhandled exceptions and returns a generic 500 Internal Server Error response.


How do you handle HTTP 404 errors in FastAPI?

FastAPI automatically handles 404 errors when a requested route does not exist. However, you can customize the response for 404 errors by creating a custom exception handler for 404 Not Found errors.

Example of handling 404 errors:

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

app = FastAPI()

@app.exception_handler(404)
def not_found_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=404,
        content={"message": "The resource you requested was not found."},
    )

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

In this example, a custom handler for 404 errors returns a specific message when a route or resource is not found.


How do you log errors and exceptions in FastAPI?

FastAPI provides the ability to log errors and exceptions using the logging module. You can log exceptions in your custom exception handlers to keep track of errors in your application.

Example of logging errors:

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

app = FastAPI()
logger = logging.getLogger(__name__)

class CustomException(Exception):
    def __init__(self, name: str):
        self.name = name

@app.exception_handler(CustomException)
def custom_exception_handler(request: Request, exc: CustomException):
    logger.error(f"Error: {exc.name}")
    return JSONResponse(
        status_code=400,
        content={"message": f"Oops! {exc.name} caused an error."},
    )

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id != 1:
        raise CustomException(name="Invalid Item")
    return {"item_id": item_id}

In this example, errors are logged using the logging module whenever the CustomException is raised.


How do you return custom error responses with FastAPI?

FastAPI allows you to return custom error responses by raising HTTPException or by defining custom exception handlers. You can return custom status codes, error messages, and even custom headers in the response.

Example of returning a custom error response:

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id != 1:
        raise HTTPException(
            status_code=400,
            detail="Custom error message for invalid item.",
            headers={"X-Error": "There goes my error"},
        )
    return {"item_id": item_id}

In this example, a custom error response is returned with a status code of 400 Bad Request, a custom error message, and an additional header X-Error.


How do you handle security-related errors in FastAPI?

FastAPI provides built-in support for handling security-related errors such as authentication and authorization failures. You can use HTTPException to return a 401 Unauthorized or 403 Forbidden response when a security violation occurs.

Example of handling security errors:

from fastapi import FastAPI, HTTPException, Depends
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.get("/secure-items/")
def read_secure_items(token: str = Depends(oauth2_scheme)):
    if token != "valid_token":
        raise HTTPException(status_code=401, detail="Invalid token")
    return {"message": "Access granted"}

In this example, FastAPI returns a 401 Unauthorized error if the provided token is not valid, indicating that the user is not authenticated.

Ads