| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- """
- 全局异常处理器
- 处理各类异常并返回统一格式的错误响应
- 需求: 7.3, 8.1, 8.2, 8.3, 8.4
- """
- import logging
- from fastapi import Request, FastAPI, HTTPException
- from fastapi.responses import JSONResponse
- from fastapi.exceptions import RequestValidationError
- from sqlalchemy.exc import SQLAlchemyError
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
- )
- logger = logging.getLogger(__name__)
- def register_exception_handlers(app: FastAPI):
- """注册全局异常处理器"""
- @app.exception_handler(HTTPException)
- async def http_exception_handler(request: Request, exc: HTTPException):
- """HTTP异常处理"""
- logger.warning(f"HTTP error {exc.status_code}: {exc.detail}")
- if isinstance(exc.detail, dict):
- payload = {"data": None}
- payload.update(exc.detail)
- else:
- payload = {
- "code": exc.status_code,
- "message": exc.detail,
- "detail": exc.detail,
- "data": None
- }
- return JSONResponse(
- status_code=exc.status_code,
- content=payload
- )
-
- @app.exception_handler(RequestValidationError)
- async def validation_exception_handler(request: Request, exc: RequestValidationError):
- """参数验证错误处理"""
- errors = exc.errors()
- logger.warning(f"Validation error: {errors}")
- # 提取第一条错误的友好提示,避免将原始列表暴露给前端
- if errors:
- first_error = errors[0]
- message = first_error.get("msg", "请求参数错误")
- # 去掉 Pydantic 自动添加的 "Value error, " 前缀
- if message.startswith("Value error, "):
- message = message[len("Value error, "):]
- else:
- message = "请求参数错误"
- return JSONResponse(
- status_code=400,
- content={"code": 400, "message": message, "data": None}
- )
-
- @app.exception_handler(SQLAlchemyError)
- async def database_exception_handler(request: Request, exc: SQLAlchemyError):
- """数据库错误处理"""
- logger.error(f"Database error: {exc}")
- return JSONResponse(
- status_code=500,
- content={"code": 500, "message": "Database error", "data": None}
- )
-
- @app.exception_handler(Exception)
- async def global_exception_handler(request: Request, exc: Exception):
- """全局异常处理"""
- logger.error(f"Unhandled exception: {exc}")
- return JSONResponse(
- status_code=500,
- content={"code": 500, "message": "Internal server error", "data": None}
- )
|