11import orjson
22from fastapi import FastAPI , Request
3+ from fastapi .exceptions import ResponseValidationError
34from fastapi .responses import JSONResponse
45from rotoger import AppStructLogger
56from sqlalchemy .exc import SQLAlchemyError
67
78logger = AppStructLogger ().get_logger ()
89
9- #TODO: add reasoning for this in readme plus higligh using re-raise in db session
10+
11+ # TODO: add reasoning for this in readme plus higligh using re-raise in db session
1012async def sqlalchemy_exception_handler (
1113 request : Request , exc : SQLAlchemyError
1214) -> JSONResponse :
@@ -30,6 +32,51 @@ async def sqlalchemy_exception_handler(
3032 )
3133
3234
35+ async def response_validation_exception_handler (
36+ request : Request , exc : ResponseValidationError
37+ ) -> JSONResponse :
38+ request_path = request .url .path
39+ try :
40+ raw_body = await request .body ()
41+ request_body = orjson .loads (raw_body ) if raw_body else None
42+ except orjson .JSONDecodeError :
43+ request_body = None
44+
45+ errors = exc .errors ()
46+
47+ # Check if this is a None/null response case
48+ is_none_response = False
49+ for error in errors :
50+ # Check for null input pattern
51+ if error .get ("input" ) is None and "valid dictionary" in error .get ("msg" , "" ):
52+ is_none_response = True
53+ break
54+
55+ await logger .aerror (
56+ "Response validation error occurred" ,
57+ validation_errors = errors ,
58+ request_url = request_path ,
59+ request_body = request_body ,
60+ is_none_response = is_none_response ,
61+ )
62+
63+ if is_none_response :
64+ # Return 404 when response is None (resource not found)
65+ return JSONResponse (
66+ status_code = 404 ,
67+ content = {"no_response" : "The requested resource was not found" },
68+ )
69+ else :
70+ # Return 422 when response exists but doesn't match expected format
71+ return JSONResponse (
72+ status_code = 422 ,
73+ content = {"response_format_error" : errors },
74+ )
75+
76+
3377def register_exception_handlers (app : FastAPI ) -> None :
3478 """Register all exception handlers with the FastAPI app."""
3579 app .add_exception_handler (SQLAlchemyError , sqlalchemy_exception_handler )
80+ app .add_exception_handler (
81+ ResponseValidationError , response_validation_exception_handler
82+ )
0 commit comments