from fastapi import HTTPException, Request from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError import logging from app.schemas.response import ErrorResponse # 创建日志记录器 logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) class BusinessError(Exception): """业务错误异常,使用标准响应格式""" def __init__(self, message: str, code: int = 500): self.message = message self.code = code super().__init__(self.message) # 业务异常处理器 async def business_exception_handler(request: Request, exc: BusinessError): """将业务异常转换为标准响应格式""" logger.debug(f"处理业务异常: code={exc.code}, message={exc.message}") error_response = ErrorResponse( code=exc.code, message=exc.message ) return JSONResponse( status_code=200, # 始终返回200状态码,业务错误码在响应内容中 content=error_response.model_dump() ) # 请求验证错误处理器 async def validation_exception_handler(request: Request, exc: RequestValidationError): """将请求验证错误转换为标准错误响应""" error_messages = [] for error in exc.errors(): loc = error.get("loc", []) loc_str = " -> ".join(str(l) for l in loc) error_messages.append(f"{loc_str}: {error.get('msg')}") error_message = ", ".join(error_messages) logger.debug(f"处理请求验证错误: {error_message}") error_response = ErrorResponse( code=422, message=f"请求参数验证错误: {error_message}" ) return JSONResponse( status_code=200, # 与业务异常一致,返回200状态码 content=error_response.model_dump() ) # HTTP异常处理器 async def http_exception_handler(request: Request, exc: HTTPException): """将HTTP异常转换为标准错误响应""" logger.debug(f"处理HTTP异常: status_code={exc.status_code}, detail={exc.detail}") error_response = ErrorResponse( code=exc.status_code, message=str(exc.detail) ) return JSONResponse( status_code=exc.status_code, content=exc.detail ) def add_exception_handlers(app): """添加异常处理器到FastAPI应用""" app.add_exception_handler(BusinessError, business_exception_handler) app.add_exception_handler(RequestValidationError, validation_exception_handler) app.add_exception_handler(HTTPException, http_exception_handler)