from fastapi.exceptions import ( HTTPException, RequestValidationError, ResponseValidationError, ) from fastapi.requests import Request from fastapi.responses import JSONResponse from tortoise.exceptions import DoesNotExist, IntegrityError from app.http_base import HttpResp import logging logger = logging.getLogger(__name__) class SettingNotFound(Exception): pass class AssertException(Exception): """断言异常""" def __init__(self, message: str, code: int = 1001): self.message = message self.code = code super().__init__(message) async def DoesNotExistHandle(req: Request, exc: DoesNotExist) -> JSONResponse: """处理对象不存在异常""" resp = HttpResp.REQUEST_404_ERROR content = dict( code=resp.code, msg=f"Object has not found, exc: {exc}, query_params: {req.query_params}", data=None ) logger.warning(f"Object not found: {exc}, path: {req.url.path}") return JSONResponse(content=content, status_code=200) async def IntegrityHandle(req: Request, exc: IntegrityError) -> JSONResponse: """处理数据完整性异常""" resp = HttpResp.SYSTEM_ERROR content = dict( code=resp.code, msg=f"IntegrityError: {str(exc)}", data=None ) logger.error(f"Integrity error: {exc}, path: {req.url.path}", exc_info=True) return JSONResponse(content=content, status_code=200) async def HttpExcHandle(req: Request, exc: HTTPException) -> JSONResponse: """处理 HTTP 异常""" content = dict( code=exc.status_code, msg=exc.detail, data=None ) logger.warning(f"HTTP exception: {exc.status_code} - {exc.detail}, path: {req.url.path}") return JSONResponse(content=content, status_code=200) async def RequestValidationHandle(req: Request, exc: RequestValidationError) -> JSONResponse: """处理请求验证异常""" resp = HttpResp.PARAMS_VALID_ERROR errors = [] for error in exc.errors(): errors.append({ "loc": error["loc"], "msg": error["msg"], "type": error["type"] }) content = dict( code=resp.code, msg=f"{resp.msg}, errors: {errors}", data=errors ) logger.warning(f"Request validation error: {errors}, path: {req.url.path}") return JSONResponse(content=content, status_code=200) async def ResponseValidationHandle(req: Request, exc: ResponseValidationError) -> JSONResponse: """处理响应验证异常""" resp = HttpResp.SYSTEM_ERROR content = dict( code=resp.code, msg=f"Response validation error: {str(exc)}", data=None ) logger.error(f"Response validation error: {exc}, path: {req.url.path}", exc_info=True) return JSONResponse(content=content, status_code=200) async def AssertExceptionHandle(request: Request, exc: AssertException) -> JSONResponse: """处理断言异常""" resp = HttpResp.ASSERT_ARGUMENT_ERROR content = dict( code=exc.code, msg=exc.message, data=None ) logger.warning(f"Assert exception: {exc.message}, path: {request.url.path}") return JSONResponse( content=content, status_code=200 ) async def AssertionErrorHandle(request: Request, exc: AssertionError) -> JSONResponse: """处理 Python assert 异常""" resp = HttpResp.ASSERT_ARGUMENT_ERROR message = str(exc) if exc.args else resp.msg content = dict( code=resp.code, msg=message, data=None ) logger.warning(f"Assertion error: {message}, path: {request.url.path}") return JSONResponse( content=content, status_code=200 ) async def GlobalExceptionHandler(request: Request, exc: Exception) -> JSONResponse: """全局异常处理器""" resp = HttpResp.SYSTEM_ERROR content = dict( code=resp.code, msg=f"{resp.msg}: {str(exc)}", data=None ) logger.error(f"Global exception: {str(exc)}, path: {request.url.path}", exc_info=True) return JSONResponse( content=content, status_code=200 ) # 便捷函数用于注册所有异常处理器 def register_exception_handlers(app): """注册所有异常处理器到 FastAPI 应用""" app.add_exception_handler(DoesNotExist, DoesNotExistHandle) app.add_exception_handler(IntegrityError, IntegrityHandle) app.add_exception_handler(HTTPException, HttpExcHandle) app.add_exception_handler(RequestValidationError, RequestValidationHandle) app.add_exception_handler(ResponseValidationError, ResponseValidationHandle) app.add_exception_handler(AssertException, AssertExceptionHandle) app.add_exception_handler(AssertionError, AssertionErrorHandle) # 捕获 Python assert app.add_exception_handler(Exception, GlobalExceptionHandler) # 全局异常处理器