diff --git a/framework/hosting/simple_module_hosting/_error_handlers.py b/framework/hosting/simple_module_hosting/_error_handlers.py index 6e2092ee..cf861a77 100644 --- a/framework/hosting/simple_module_hosting/_error_handlers.py +++ b/framework/hosting/simple_module_hosting/_error_handlers.py @@ -4,6 +4,8 @@ import logging +from fastapi.encoders import jsonable_encoder +from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse from inertia import ( Inertia, @@ -49,6 +51,18 @@ async def not_found_error_handler(request: Request, exc: NotFoundError) -> Respo return await render_error_page(request, 404, str(exc)) +async def request_validation_error_handler( + request: Request, exc: RequestValidationError +) -> Response: + """Return an Inertia error page for browser requests with invalid params.""" + accept = request.headers.get("accept", "") + if "text/html" in accept: + return await render_error_page( + request, 422, "The requested URL contains invalid parameters." + ) + return JSONResponse(status_code=422, content={"detail": jsonable_encoder(exc.errors())}) + + async def unhandled_exception_handler(request: Request, exc: Exception) -> Response: logger.exception("Unhandled exception: %s", exc) return await render_error_page(request, 500, "") diff --git a/framework/hosting/simple_module_hosting/_phase_helpers.py b/framework/hosting/simple_module_hosting/_phase_helpers.py index 743c3440..888337a5 100644 --- a/framework/hosting/simple_module_hosting/_phase_helpers.py +++ b/framework/hosting/simple_module_hosting/_phase_helpers.py @@ -12,6 +12,7 @@ from typing import TYPE_CHECKING from fastapi import APIRouter, FastAPI +from fastapi.exceptions import RequestValidationError from fastapi.routing import APIRoute from fastapi.staticfiles import StaticFiles from inertia import ( @@ -26,6 +27,7 @@ from simple_module_hosting._error_handlers import ( http_exception_handler, not_found_error_handler, + request_validation_error_handler, unhandled_exception_handler, ) from simple_module_hosting.i18n_middleware import LocaleMiddleware @@ -53,6 +55,7 @@ def register_exception_handlers(app: FastAPI, modules: list) -> None: ) app.add_exception_handler(HTTPException, http_exception_handler) app.add_exception_handler(NotFoundError, not_found_error_handler) + app.add_exception_handler(RequestValidationError, request_validation_error_handler) app.add_exception_handler(Exception, unhandled_exception_handler) for mod in modules: mod.register_exception_handlers(app)