74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
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) |