初始话项目框架
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import traceback
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
from app.config import settings
|
||||
from app.core.logger import log
|
||||
from app.core.schemas.responses import StandardResponse
|
||||
|
||||
# 友好的 HTTP 状态码消息映射
|
||||
_FRIENDLY_MESSAGES = {
|
||||
400: "请求参数错误",
|
||||
401: "未经授权,请登录",
|
||||
403: "权限不足,禁止访问",
|
||||
404: "请求的资源不存在",
|
||||
405: "请求方法不允许",
|
||||
422: "数据验证失败",
|
||||
429: "请求过于频繁",
|
||||
500: "服务器内部错误",
|
||||
}
|
||||
|
||||
|
||||
def _get_uuid(request: Request) -> str | None:
|
||||
return getattr(request.state, "uuid", None)
|
||||
|
||||
|
||||
async def http_exception_handler(request: Request, exc: StarletteHTTPException) -> JSONResponse:
|
||||
uuid = _get_uuid(request)
|
||||
log.error(f"HTTPException -- uuid: {uuid} | status: {exc.status_code} | msg: {exc.detail}")
|
||||
message = _FRIENDLY_MESSAGES.get(exc.status_code, str(exc.detail))
|
||||
return JSONResponse(
|
||||
status_code=exc.status_code,
|
||||
content=StandardResponse.fail(msg=message, code=exc.status_code, uuid=uuid).model_dump(),
|
||||
)
|
||||
|
||||
|
||||
async def validation_exception_handler(request: Request, exc: RequestValidationError) -> JSONResponse:
|
||||
uuid = _get_uuid(request)
|
||||
errors = exc.errors()
|
||||
log.error(f"ValidationError -- uuid: {uuid} | errors: {errors}")
|
||||
return JSONResponse(
|
||||
status_code=422,
|
||||
content=StandardResponse.fail(msg="数据验证失败", code=422, data=errors, uuid=uuid).model_dump(),
|
||||
)
|
||||
|
||||
|
||||
async def assertion_error_handler(request: Request, exc: AssertionError) -> JSONResponse:
|
||||
uuid = _get_uuid(request)
|
||||
log.error(f"AssertionError -- uuid: {uuid} | msg: {exc}\n{traceback.format_exc()}")
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content=StandardResponse.fail(msg=f"断言错误: {exc}", uuid=uuid).model_dump(),
|
||||
)
|
||||
|
||||
|
||||
async def global_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
||||
uuid = _get_uuid(request)
|
||||
log.error(f"Unhandled Exception -- uuid: {uuid} | msg: {exc}\n{traceback.format_exc()}")
|
||||
msg = str(exc) if settings.env == "dev" else "服务器内部错误"
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content=StandardResponse.fail(msg=msg, uuid=uuid).model_dump(),
|
||||
)
|
||||
|
||||
|
||||
def register_exception_handlers(app) -> None:
|
||||
"""将异常处理器挂载到 FastAPI 应用"""
|
||||
app.add_exception_handler(StarletteHTTPException, http_exception_handler)
|
||||
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
||||
app.add_exception_handler(AssertionError, assertion_error_handler)
|
||||
app.add_exception_handler(Exception, global_exception_handler)
|
||||
Reference in New Issue
Block a user