aidress/app/exceptions/http_exception.py
2025-03-21 23:22:54 +08:00

82 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)