1- from .api_exception import APIException
2- from starlette .responses import JSONResponse
3- from typing import Any , Dict
1+ import logging
42import os
3+ from typing import Any , Dict , Optional
4+
5+ from fastapi .exceptions import RequestValidationError
6+ from pydantic import ValidationError
7+ from starlette .requests import Request
8+ from starlette .responses import JSONResponse
9+
10+ from .api_exception import APIException
511
612
713class APIExceptionHandler :
814 error_label = "errorCode"
915 message_label = "message"
1016
1117 @classmethod
12- async def handled (cls , exc : APIException , body_extra : Dict = None , ** kwargs : Any ) -> JSONResponse :
13- body_content = {cls .error_label : exc .get_error_code (), cls .message_label : str (exc )}
18+ def handled (
19+ cls , request : Request , exc : APIException , body_extra : Optional [Dict ] = None , ** kwargs : Any
20+ ) -> JSONResponse :
21+ body_content = {
22+ cls .error_label : exc .get_error_code (),
23+ cls .message_label : str (exc ),
24+ }
1425 if body_extra is not None :
1526 body_content = {** body_content , ** body_extra }
1627
@@ -21,6 +32,36 @@ async def handled(cls, exc: APIException, body_extra: Dict = None, **kwargs: Any
2132 return JSONResponse (status_code = exc .status_code , content = body_content , ** kwargs )
2233
2334 @classmethod
24- async def unhandled (cls , exc : Exception , body_extra : Dict = None , ** kwargs : Any ) -> JSONResponse :
35+ def unhandled (
36+ cls , request : Request , exc : Exception , body_extra : Optional [Dict ] = None , ** kwargs : Any
37+ ) -> JSONResponse :
2538 api_exc = APIException (exc = exc )
26- return await cls .handled (api_exc , body_extra , ** kwargs )
39+ return cls .handled (request , api_exc , body_extra , ** kwargs )
40+
41+ @classmethod
42+ def handle_exception (
43+ cls ,
44+ request : Request ,
45+ exc : Exception ,
46+ capture_unhandled : bool = True ,
47+ capture_validation : bool = False ,
48+ log_error : bool = True ,
49+ logger_name : str = "app.exception_handler" ,
50+ ) -> JSONResponse :
51+ logger = logging .getLogger (logger_name ) if log_error else None
52+
53+ if issubclass (type (exc ), APIException ):
54+ if log_error :
55+ logger .error (str (exc ))
56+ return APIExceptionHandler .handled (request , exc ) # type: ignore
57+
58+ if log_error :
59+ logger .error (str (exc ))
60+
61+ if issubclass (type (exc ), (RequestValidationError , ValidationError )) and not capture_validation :
62+ raise
63+
64+ if not capture_unhandled :
65+ raise
66+
67+ return APIExceptionHandler .unhandled (request , exc )
0 commit comments