first commit
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
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) # 全局异常处理器
|
||||
Reference in New Issue
Block a user