2022-07-06

Customizing Default 422 Error in FastAPI

Introduction

In this article, I will introduce how to customize the default 422 error in FastAPI, which typically indicates a validation error in a client's request. We'll explore two main tasks: overriding the default exception handlers to define a custom response for RequestValidationError, and altering the OpenAPI document to remove the default 422 error response from it.

Customizing Default 422 Error in FastAPI

We will go through the process of customizing the default 422 error in FastAPI. This involves overriding the default exception handler for RequestValidationError and creating a custom validation error response.

Overriding Default Exception Handlers

To override the default exception handler for RequestValidationError, follow these steps:

  1. Import the necessary modules and create a new FastAPI application instance:
python
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError

app = FastAPI()
  1. Define a custom exception handler function. This function should accept a Request object and the raised RequestValidationError exception. The function should return a custom response, such as a JSONResponse:
python
async def custom_request_validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=422,
        content={
            "error_code": "CUSTOM_VALIDATION_ERROR",
            "message": "One or more request parameters failed validation",
            "detail": exc.errors(),
        },
    )
  1. Register the custom exception handler with the FastAPI application instance:
python
app.exception_handler(RequestValidationError)(custom_request_validation_exception_handler)

Creating Custom Validation Error Response

To create a custom validation error response, follow these steps:

  1. Define a custom response model using Pydantic. This model should include the fields that you want to return in the custom error response:
python
from pydantic import BaseModel

class CustomValidationError(BaseModel):
    error_code: str
    message: str
    detail: List[Dict[str, Any]]
  1. Update the custom exception handler function to use the custom response model:
python
async def custom_request_validation_exception_handler(request: Request, exc: RequestValidationError):
    custom_error = CustomValidationError(
        error_code="CUSTOM_VALIDATION_ERROR",
        message="One or more request parameters failed validation",
        detail=exc.errors(),
    )
    return JSONResponse(status_code=422, content=custom_error.dict())

By following these steps, you have successfully customized the default 422 error in FastAPI. The custom error response will now be returned whenever a RequestValidationError is raised.

Removing Default 422 Error from OpenAPI Document

FastAPI automatically generates an OpenAPI document for your API, which includes information about possible responses from your endpoints. By default, the OpenAPI document includes a 422 error response for all endpoints, indicating potential validation errors.

In some cases, you may want to remove this default 422 error from the OpenAPI document. This can be done by customizing the app.openapi() method. Here's how to accomplish this:

  1. After defining your FastAPI application instance, you need to override the app.openapi() method:
python
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        title="Custom schema",
        version="2.5.0",
        description="This is a very custom OpenAPI schema",
        routes=app.routes,
    )
    openapi_schema["paths"].pop("/openapi.json")
    app.openapi_schema = openapi_schema
    return app.openapi_schema

app.openapi = custom_openapi

In the code above, the custom_openapi() function retrieves the existing OpenAPI schema if it exists, and if it doesn't, it generates a new one. The openapi_schema["paths"].pop("/openapi.json") line removes the OpenAPI JSON route from the schema.

  1. Modify the custom_openapi() function to remove the default 422 error from the OpenAPI schema:
python
def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        title="Custom schema",
        version="2.5.0",
        description="This is a very custom OpenAPI schema",
        routes=app.routes,
    )
    for path, path_dict in openapi_schema["paths"].items():
        for method, method_dict in path_dict.items():
            method_dict.pop("responses", {}).pop("422", None)
    app.openapi_schema = openapi_schema
    return app.openapi_schema

The updated custom_openapi() function now iterates over all paths and methods in the OpenAPI schema and removes the 422 response if it exists.

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!