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 ) )