151 lines
4.8 KiB
Python
151 lines
4.8 KiB
Python
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) # 全局异常处理器
|