| | """
|
| | Global error handling for FastAPI application.
|
| |
|
| | Provides exception handlers for consistent error responses.
|
| | """
|
| |
|
| | from fastapi import FastAPI
|
| | from fastapi import HTTPException
|
| | from fastapi import Request
|
| | from fastapi.exceptions import RequestValidationError
|
| | from starlette.responses import JSONResponse
|
| |
|
| | from app.utils.logger import get_logger
|
| |
|
| | logger = get_logger(__name__)
|
| |
|
| |
|
| | async def validation_exception_handler(
|
| | request: Request,
|
| | exc: RequestValidationError,
|
| | ) -> JSONResponse:
|
| | """
|
| | Handle Pydantic validation errors.
|
| |
|
| | Formats validation errors into a consistent response format.
|
| |
|
| | Args:
|
| | request: Incoming request
|
| | exc: Validation exception
|
| |
|
| | Returns:
|
| | JSON response with error details
|
| | """
|
| | errors = exc.errors()
|
| |
|
| |
|
| | error_messages = []
|
| | for error in errors:
|
| | loc = " -> ".join(str(x) for x in error.get("loc", []))
|
| | msg = error.get("msg", "Validation error")
|
| | error_messages.append(f"{loc}: {msg}")
|
| |
|
| | logger.warning(
|
| | "Validation error",
|
| | path=request.url.path,
|
| | errors=error_messages,
|
| | )
|
| |
|
| | return JSONResponse(
|
| | status_code=422,
|
| | content={
|
| | "status": "error",
|
| | "message": "Validation error",
|
| | "details": {
|
| | "errors": error_messages,
|
| | },
|
| | },
|
| | )
|
| |
|
| |
|
| | async def http_exception_handler(
|
| | request: Request,
|
| | exc: HTTPException,
|
| | ) -> JSONResponse:
|
| | """
|
| | Handle HTTP exceptions.
|
| |
|
| | Formats HTTP exceptions into a consistent response format.
|
| |
|
| | Args:
|
| | request: Incoming request
|
| | exc: HTTP exception
|
| |
|
| | Returns:
|
| | JSON response with error details
|
| | """
|
| | return JSONResponse(
|
| | status_code=exc.status_code,
|
| | content={
|
| | "status": "error",
|
| | "message": exc.detail,
|
| | },
|
| | headers=exc.headers,
|
| | )
|
| |
|
| |
|
| | async def general_exception_handler(
|
| | request: Request,
|
| | exc: Exception,
|
| | ) -> JSONResponse:
|
| | """
|
| | Handle unexpected exceptions.
|
| |
|
| | Logs the exception and returns a generic error response.
|
| |
|
| | Args:
|
| | request: Incoming request
|
| | exc: Unexpected exception
|
| |
|
| | Returns:
|
| | JSON response with generic error message
|
| | """
|
| | logger.exception(
|
| | "Unhandled exception",
|
| | path=request.url.path,
|
| | method=request.method,
|
| | error=str(exc),
|
| | )
|
| |
|
| | return JSONResponse(
|
| | status_code=500,
|
| | content={
|
| | "status": "error",
|
| | "message": "Internal server error",
|
| | },
|
| | )
|
| |
|
| |
|
| | def setup_exception_handlers(app: FastAPI) -> None:
|
| | """
|
| | Register all exception handlers with the FastAPI app.
|
| |
|
| | Args:
|
| | app: FastAPI application instance
|
| | """
|
| | app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
| | app.add_exception_handler(HTTPException, http_exception_handler)
|
| | app.add_exception_handler(Exception, general_exception_handler)
|
| |
|
| | logger.debug("Exception handlers registered")
|
| |
|