Program/mooc/core/exceptions.py

66 lines
2.3 KiB
Python
Raw Normal View History

from fastapi import Request, status
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException
from typing import Union, Dict, Any
from mooc.core.response import ResponseFactory
from mooc.core.logger import get_logger
logger = get_logger(__name__)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""处理请求参数验证错误"""
logger.warning(f"Request validation error: {exc.errors()}")
# 格式化错误信息
error_details = []
for error in exc.errors():
error_details.append({
"loc": error.get("loc", []),
"msg": error.get("msg", ""),
"type": error.get("type", "")
})
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=ResponseFactory.failed_validation(
msg="请求参数验证失败",
errors=error_details
)
)
async def http_exception_handler(request: Request, exc: HTTPException):
"""处理HTTP异常"""
logger.warning(f"HTTP exception: {exc.status_code} - {exc.detail}")
# 根据状态码选择适当的响应生成方法
if exc.status_code == status.HTTP_404_NOT_FOUND:
content = ResponseFactory.not_found(msg=str(exc.detail))
elif exc.status_code == status.HTTP_401_UNAUTHORIZED:
content = ResponseFactory.unauthorized(msg=str(exc.detail))
elif exc.status_code == status.HTTP_403_FORBIDDEN:
content = ResponseFactory.forbidden(msg=str(exc.detail))
else:
content = ResponseFactory.error(
code=exc.status_code,
msg=str(exc.detail)
)
return JSONResponse(
status_code=exc.status_code,
content=content,
headers=exc.headers or {}
)
async def generic_exception_handler(request: Request, exc: Exception):
"""处理所有其他未捕获的异常"""
logger.exception(f"Unhandled exception: {str(exc)}")
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=ResponseFactory.server_error(
msg="服务器内部错误",
data={"detail": str(exc)} if not isinstance(exc, AssertionError) else None
)
)