Download backend/app/core/exceptions.py from anky2002/best: direct link, hf CLI and curl.
- Browser
- Download file 3.01 kB
-
https://huggingface.co/anky2002/best/resolve/main/backend/app/core/exceptions.py
- Command line
-
hf download hf://anky2002/best/backend/app/core/exceptions.py
-
curl -L -o exceptions.py https://huggingface.co/anky2002/best/resolve/main/backend/app/core/exceptions.py
3.01 kB
| """ | |
| Global exception handlers and error formatting. | |
| """ | |
| import logging | |
| import traceback | |
| from fastapi import FastAPI, Request, status | |
| from fastapi.exceptions import RequestValidationError | |
| from fastapi.responses import JSONResponse | |
| from starlette.exceptions import HTTPException as StarletteHTTPException | |
| from app.core.config import settings | |
| logger = logging.getLogger(__name__) | |
| def register_exception_handlers(app: FastAPI): | |
| """Register all global exception handlers.""" | |
| async def http_exception_handler(request: Request, exc: StarletteHTTPException): | |
| """Handle HTTP exceptions with consistent format.""" | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content={ | |
| "error": True, | |
| "status_code": exc.status_code, | |
| "detail": exc.detail, | |
| "path": str(request.url.path), | |
| }, | |
| headers=getattr(exc, "headers", None), | |
| ) | |
| async def validation_exception_handler(request: Request, exc: RequestValidationError): | |
| """Handle Pydantic validation errors with readable messages.""" | |
| errors = [] | |
| for error in exc.errors(): | |
| field = " → ".join(str(loc) for loc in error["loc"][1:]) # Skip 'body' | |
| errors.append({ | |
| "field": field, | |
| "message": error["msg"], | |
| "type": error["type"], | |
| }) | |
| return JSONResponse( | |
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, | |
| content={ | |
| "error": True, | |
| "status_code": 422, | |
| "detail": "Validation error", | |
| "errors": errors, | |
| "path": str(request.url.path), | |
| }, | |
| ) | |
| async def general_exception_handler(request: Request, exc: Exception): | |
| """Handle unexpected exceptions.""" | |
| error_id = id(exc) | |
| logger.error( | |
| f"Unhandled exception [{error_id}]: {exc}\n" | |
| f"Path: {request.url.path}\n" | |
| f"{''.join(traceback.format_exception(type(exc), exc, exc.__traceback__))}" | |
| ) | |
| # In production, don't leak error details | |
| if settings.APP_ENV == "production": | |
| detail = "An unexpected error occurred. Please try again later." | |
| else: | |
| detail = f"{type(exc).__name__}: {str(exc)}" | |
| # Report to Sentry if configured | |
| try: | |
| import sentry_sdk | |
| sentry_sdk.capture_exception(exc) | |
| except ImportError: | |
| pass | |
| return JSONResponse( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| content={ | |
| "error": True, | |
| "status_code": 500, | |
| "detail": detail, | |
| "error_id": str(error_id), | |
| "path": str(request.url.path), | |
| }, | |
| ) | |