82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
from fastapi import FastAPI, Request
|
||
from fastapi.responses import JSONResponse
|
||
from fastapi.exceptions import RequestValidationError
|
||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||
import os
|
||
import traceback
|
||
import logging
|
||
|
||
from app.models.api_response import APIResponseModel
|
||
|
||
# 根据环境变量决定是否使用标准响应格式
|
||
use_standard_response = os.environ.get("USE_STANDARD_RESPONSE") == "1"
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class CustomHTTPException(Exception):
|
||
"""自定义HTTP异常类,用于抛出自定义的HTTP错误"""
|
||
def __init__(self, status_code: int, detail: str = None):
|
||
self.status_code = status_code
|
||
self.detail = detail
|
||
|
||
async def http_exception_handler(request: Request, exc: CustomHTTPException):
|
||
"""处理自定义HTTP异常的处理器"""
|
||
logger.error(f"HTTP错误: {exc.status_code} - {exc.detail}")
|
||
|
||
return JSONResponse(
|
||
status_code=exc.status_code,
|
||
content=APIResponseModel(
|
||
code=exc.status_code,
|
||
message=exc.detail or "请求处理失败"
|
||
).dict()
|
||
)
|
||
|
||
async def starlette_exception_handler(request: Request, exc: StarletteHTTPException):
|
||
"""处理FastAPI内置的HTTP异常的处理器"""
|
||
logger.error(f"Starlette HTTP错误: {exc.status_code} - {exc.detail}")
|
||
|
||
return JSONResponse(
|
||
status_code=exc.status_code,
|
||
content=APIResponseModel(
|
||
code=exc.status_code,
|
||
message=str(exc.detail)
|
||
).dict()
|
||
)
|
||
|
||
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
||
"""处理请求验证错误的处理器"""
|
||
error_detail = exc.errors()
|
||
error_messages = [f"{e['loc'][-1]}: {e['msg']}" for e in error_detail]
|
||
error_message = ", ".join(error_messages)
|
||
logger.error(f"请求验证错误: {error_message}")
|
||
|
||
return JSONResponse(
|
||
status_code=422,
|
||
content=APIResponseModel(
|
||
code=422,
|
||
message=f"请求参数验证失败: {error_message}",
|
||
data=error_detail
|
||
).dict()
|
||
)
|
||
|
||
async def general_exception_handler(request: Request, exc: Exception):
|
||
"""处理一般性异常的处理器"""
|
||
# 记录详细的错误信息
|
||
error_msg = str(exc)
|
||
logger.error(f"服务器错误: {error_msg}")
|
||
logger.error(traceback.format_exc())
|
||
|
||
return JSONResponse(
|
||
status_code=500,
|
||
content=APIResponseModel(
|
||
code=500,
|
||
message="服务器内部错误",
|
||
data={"detail": error_msg} if os.environ.get("DEBUG") == "1" else None
|
||
).dict()
|
||
)
|
||
|
||
def setup_exception_handlers(app: FastAPI):
|
||
"""为FastAPI应用设置所有异常处理器"""
|
||
app.add_exception_handler(CustomHTTPException, http_exception_handler)
|
||
app.add_exception_handler(StarletteHTTPException, starlette_exception_handler)
|
||
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
||
app.add_exception_handler(Exception, general_exception_handler) |