Spaces:
Sleeping
Sleeping
Download backend/app/core/errors.py from Aynkhn/Face-Expression-Analyzer: direct link, hf CLI and curl.
- Browser
- Download file 2.58 kB
-
https://huggingface.co/spaces/Aynkhn/Face-Expression-Analyzer/resolve/main/backend/app/core/errors.py
- Command line
-
hf download hf://spaces/Aynkhn/Face-Expression-Analyzer/backend/app/core/errors.py
-
curl -L -o errors.py https://huggingface.co/spaces/Aynkhn/Face-Expression-Analyzer/resolve/main/backend/app/core/errors.py
2.58 kB
| """Exception handlers. | |
| The previous global handler returned ``str(exc)`` in the response body. For a | |
| SQLAlchemy failure that string contains the connection URL, including the password, | |
| so a single database hiccup leaked the credentials to whoever triggered it. | |
| Here the traceback is logged server-side against a request id, and the client gets | |
| only that id. In development the detail is included, because debugging locally | |
| against an opaque error is miserable and there is no secret worth protecting. | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| from fastapi import FastAPI, HTTPException, Request, status | |
| from fastapi.exceptions import RequestValidationError | |
| from fastapi.responses import JSONResponse | |
| from app.core.config import Settings | |
| logger = logging.getLogger("facevision.errors") | |
| def _request_id(request: Request) -> str: | |
| return getattr(request.state, "request_id", "unknown") | |
| def register_exception_handlers(app: FastAPI, settings: Settings) -> None: | |
| """Attach the handlers to ``app``.""" | |
| async def validation_exception_handler( | |
| request: Request, exc: RequestValidationError | |
| ) -> JSONResponse: | |
| # Pydantic's own error structures are safe to return: they describe the | |
| # caller's input, not the server's internals. | |
| return JSONResponse( | |
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, | |
| content={ | |
| "message": "Validation failed", | |
| "request_id": _request_id(request), | |
| "errors": exc.errors(), | |
| }, | |
| ) | |
| async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse: | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content={"message": exc.detail, "request_id": _request_id(request)}, | |
| headers=exc.headers, | |
| ) | |
| async def unhandled_exception_handler(request: Request, exc: Exception) -> JSONResponse: | |
| request_id = _request_id(request) | |
| logger.error( | |
| "unhandled exception", | |
| exc_info=exc, | |
| extra={"request_id": request_id, "path": request.url.path}, | |
| ) | |
| content: dict[str, object] = { | |
| "message": "Internal Server Error", | |
| "request_id": request_id, | |
| } | |
| if settings.is_development: | |
| content["detail"] = f"{type(exc).__name__}: {exc}" | |
| return JSONResponse(status_code=500, content=content) | |