Coverage for extensions/exception_handler.py: 89.66%
29 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
1import logging
3from fastapi import FastAPI, HTTPException, Request
4from fastapi.exceptions import RequestValidationError
5from fastapi.responses import JSONResponse
7from utils.response import APIResponse
9logger = logging.getLogger("http")
12def add_exception_handlers(app: FastAPI):
13 @app.exception_handler(HTTPException)
14 async def http_exception_handler(request: Request, exc: HTTPException):
15 status_code = exc.status_code
17 if isinstance(exc.detail, dict) and "code" in exc.detail and "message" in exc.detail:
18 return JSONResponse(status_code=status_code, content=exc.detail)
20 message = exc.detail if exc.detail else "HTTP Error"
21 data = None
23 resp = APIResponse(code=status_code, message=message, data=data)
24 return JSONResponse(status_code=status_code, content=resp.dict(exclude_none=True))
26 @app.exception_handler(RequestValidationError)
27 async def validation_exception_handler(request: Request, exc: RequestValidationError):
28 errors = {}
29 for err in exc.errors():
30 field = ".".join([str(loc) for loc in err["loc"] if isinstance(loc, (str, int))])
31 errors[field] = err["msg"]
32 resp = APIResponse(code=422, message="Validation Error", data=errors)
33 return JSONResponse(status_code=422, content=resp.dict(exclude_none=True))
35 @app.exception_handler(Exception)
36 async def internal_server_error_handler(request: Request, exc: Exception):
37 logger.error(
38 "Unhandled exception for %s %s: %s",
39 request.method,
40 request.url.path,
41 exc,
42 exc_info=(type(exc), exc, exc.__traceback__),
43 )
44 resp = APIResponse(code=500, message="Internal Server Error", data=None)
45 return JSONResponse(status_code=500, content=resp.dict(exclude_none=True))