from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from loguru import logger from .base import AppException async def app_exception_handler(request: Request, exc: AppException) -> JSONResponse: request_id = getattr(request.state, "request_id", None) logger.warning("AppException | code={} msg={}", exc.code, exc.message) return JSONResponse( status_code=exc.status_code, content={ "error": { "code": exc.code, "message": exc.message, "request_id": request_id, } }, ) async def global_exception_handler(request: Request, exc: Exception) -> JSONResponse: request_id = getattr(request.state, "request_id", None) logger.exception("Unhandled exception") return JSONResponse( status_code=500, content={ "error": { "code": "INTERNAL_ERROR", "message": "服务器内部错误", "request_id": request_id, } }, ) def register_exception_handlers(app: FastAPI) -> None: # handler 形参类型为具体异常,与 Starlette 宽签名不完全一致,忽略该告警 app.add_exception_handler(AppException, app_exception_handler) # type: ignore[arg-type] app.add_exception_handler(Exception, global_exception_handler)