RequestValidationError handler scope conflict when using APIRouter
0 reputation · 28 Dec 2022, 00:31 UTC
0 reputation · 28 Dec 2022, 00:31 UTC
Goal: Apply a custom validation error response format only to certain APIRouter instances while keeping the default behavior for other routes.
Constraint/Uncertainty: FastAPI permits registering an exception handler for RequestValidationError on an APIRouter, but the documentation does not clarify whether a router‑level handler replaces, supplements, or is ignored when a global handler is also defined. This leaves the precedence and interaction between global and router‑level handlers unspecified.
Questions: Does a router‑level RequestValidationError handler override the global handler for routes under that router? If both handlers exist, which one takes precedence? Can per‑router validation error formatting be achieved without duplicating the handler code?
34775 reputation · 28 Dec 2022, 05:14 UTC
No. In standard FastAPI, RequestValidationError handling is application-level. APIRouter has no public add_exception_handler() method, so a router-level handler cannot replace the global handler for routes under that router. If a global handler exists, it is the effective handler for validation failures from every included router unless the handler branches by request path or earlier middleware intercepts the exception.
Assumption: a standard FastAPI installation on Starlette, approximately recent 0.x to 1.x releases. Exception handlers are stored on the FastAPI/Starlette application instance, while APIRouter groups routes, dependencies, tags, and prefixes. Calling router.add_exception_handler() raises AttributeError. Path-prefix matching is a workaround, not true scope isolation, so adjust it for nested or multiply mounted routers. Verify installed FastAPI and Starlette versions if behavior differs.
RequestValidationError handler on the FastAPI app.request.url.path and match the prefix used by the target router.from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
def validation_payload(exc: RequestValidationError, code: str = 'validation_error') -> dict:
return {'code': code, 'errors': exc.errors()}
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
if request.url.path.startswith('/special-api'):
return JSONResponse(
status_code=422,
content=validation_payload(exc, code='special_api_validation_error')
)
return JSONResponse(
status_code=422,
content=validation_payload(exc)
)
hasattr(router, 'add_exception_handler') is False.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.