FastAPI: How to customise 422 exception for specific route?

2k Views Asked by At

How to replace 422 standard exception with custom exception only for one route in FastAPI?

I don't want to replace for the application project, just for one route. I read many docs, and I don't understand how to do this.

Example of route that I need to change the 422 exception:

from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()


class PayloadSchema(BaseModel):
    value_int: int
    value_str: str


@router.post('/custom')
async def custom_route(payload: PayloadSchema):
    return payload
2

There are 2 best solutions below

3
brandonscript On BEST ANSWER

You can register multiple error handlers with the router. You can re-declare the default handler, and then optionally call it depending on the path:

class PayloadSchema(BaseModel):
    value_int: int
    value_str: str

router = APIRouter()

@router.post('/standard')
async def standard_route(payload: PayloadSchema):
    return payload

@app.exception_handler(RequestValidationError)
async def standard_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}),
    )

@router.post('/custom')
async def custom_route(payload: PayloadSchema):
    return payload

@app.exception_handler(RequestValidationError)
async def custom_exception_handler(request: Request, exc: RequestValidationError):
    if (request.url.path == '/custom'):
        return JSONResponse({"error": "Bad request, must be a valid PayloadSchema format"}, status_code=400)
    else:
        return await standard_validation_exception_handler(request, exc)

app = FastAPI()
app.include_router(router)
app.add_exception_handler(RequestValidationError, custom_exception_handler)

Or you can do it directly with the @app.exception_handler decorator without the router (see FastAPI docs).

0
angwrk On

Don't forget to register the custom exception handler only for the specific route:

from fastapi import APIRouter, FastAPI, HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel

router = APIRouter()


class PayloadSchema(BaseModel):
    value_int: int
    value_str: str


@router.post('/custom')
async def custom_route(payload: PayloadSchema):
    return payload


async def custom_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse({"error": "Custom validation error message"}, status_code=400)


app = FastAPI()
app.include_router(router)

app.add_exception_handler(RequestValidationError, custom_exception_handler)