File size: 3,150 Bytes
6b408d7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | """
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()
# Format error messages
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")
|