feat: improve error handling and code quality

后端改进:
- 添加统一异常处理系统 (exceptions.py, response.py)
- 实现自定义异常类 (ValidationError, AuthorizationError, ResourceNotFoundError, BusinessLogicError)
- 配置全局异常处理器,统一 API 错误响应格式
- 迁移业务逻辑错误到自定义异常 (users.py, auth.py)
- 添加 SQL LIKE 通配符转义,防止通配符滥用
- 使用 EmailStr 进行邮箱格式验证
- 移除敏感字段暴露 (jwt_sub)

前端改进:
- 配置 ESLint 9 (flat config) 和 Prettier
- 修复所有 ESLint 错误和警告
- 移除未使用的变量和导入
- 为组件添加 PropTypes 默认值
- 统一代码格式和风格
This commit is contained in:
2026-01-03 19:01:15 +08:00
parent 523da50123
commit 5cdc8b2144
57 changed files with 4623 additions and 2754 deletions
+59 -1
View File
@@ -1,11 +1,16 @@
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from pydantic import ValidationError as PydanticValidationError
import logging
from pathlib import Path
from backend.config import settings
from backend.models import init_db
from backend.exceptions import BaseAPIException
from backend.schemas.response import ErrorResponse, ErrorDetail
# 配置日志
settings.LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
@@ -69,6 +74,59 @@ app.add_middleware(
)
# 全局异常处理器
@app.exception_handler(BaseAPIException)
async def api_exception_handler(request: Request, exc: BaseAPIException):
"""处理自定义 API 异常"""
return JSONResponse(
status_code=exc.status_code,
content=ErrorResponse(
error=ErrorDetail(
code=exc.error_code,
message=exc.message
)
).model_dump()
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""处理请求验证错误"""
errors = exc.errors()
# 取第一个错误作为主要错误消息
first_error = errors[0] if errors else {}
field = ".".join(str(loc) for loc in first_error.get("loc", []))
message = first_error.get("msg", "验证错误")
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=ErrorResponse(
error=ErrorDetail(
code="VALIDATION_ERROR",
message=message,
field=field or None
)
).model_dump()
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""处理未捕获的异常"""
logger.error(f"未处理的异常: {type(exc).__name__}: {str(exc)}", exc_info=True)
# 不向客户端暴露内部错误详情
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=ErrorResponse(
error=ErrorDetail(
code="INTERNAL_ERROR",
message="服务器内部错误,请稍后重试"
)
).model_dump()
)
# 健康检查端点
@app.get("/health")
async def health_check():