# 统一错误响应格式实现 **日期**: 2026-01-27 **类型**: 功能增强 **影响范围**: 全局 API 错误处理 ## 变更概述 实现全局异常处理器,确保所有 API 错误响应符合统一的 `ApiResponse` 格式规范。 ## 问题背景 在实现统一响应格式(RFC-135)后,发现错误响应仍使用 FastAPI 默认格式: ```json { "detail": "错误信息" } ``` 这与成功响应的 `ApiResponse` 格式不一致,导致前端需要处理两种不同的响应结构。 ## 解决方案 ### 1. 添加全局异常处理器 在 `app/main.py` 中添加三个异常处理器: #### HTTPException 处理器 ```python @app.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_code=exc.status_code, content={ "success": False, "code": exc.status_code, "message": exc.detail, "data": None, "timestamp": datetime.now(timezone.utc).isoformat() } ) ``` #### RequestValidationError 处理器 ```python @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): error_msg = "请求参数验证失败" if exc.errors(): first_error = exc.errors()[0] field = " -> ".join(str(loc) for loc in first_error.get("loc", [])) msg = first_error.get("msg", "") error_msg = f"{field}: {msg}" return JSONResponse( status_code=422, content={ "success": False, "code": 422, "message": error_msg, "data": {"errors": exc.errors()}, "timestamp": datetime.now(timezone.utc).isoformat() } ) ``` #### 通用异常处理器 ```python @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): logger.error(f"未处理的异常: {exc}", exc_info=True) return JSONResponse( status_code=500, content={ "success": False, "code": 500, "message": "服务器内部错误" if not settings.DEBUG else str(exc), "data": None, "timestamp": datetime.now(timezone.utc).isoformat() } ) ``` #### 404 错误处理器 ```python @app.exception_handler(404) async def not_found_handler(request: Request, exc): return JSONResponse( status_code=404, content={ "success": False, "code": 404, "message": "请求的资源不存在", "data": None, "timestamp": datetime.now(timezone.utc).isoformat() } ) ``` ## 测试验证 ### 1. 业务逻辑错误(400) ```bash curl -X POST "http://localhost:6170/api/v1/auth/login/phone" \ -H "Content-Type: application/json" \ -d '{"phone":"18046315592","countryCode":"+86","code":"000000"}' ``` 响应: ```json { "success": false, "code": 400, "message": "验证码错误", "data": null, "timestamp": "2026-01-27T08:23:00.310624+00:00" } ``` ### 2. 参数验证错误(422) ```bash curl -X POST "http://localhost:6170/api/v1/auth/login/phone" \ -H "Content-Type: application/json" \ -d '{"phone":"18046315592"}' ``` 响应: ```json { "success": false, "code": 422, "message": "body -> code: Field required", "data": { "errors": [...] }, "timestamp": "2026-01-27T08:23:12.388333+00:00" } ``` ### 3. 资源不存在(404) ```bash curl -X GET "http://localhost:6170/api/v1/nonexistent" ``` 响应: ```json { "success": false, "code": 404, "message": "请求的资源不存在", "data": null, "timestamp": "2026-01-27T08:24:07.692476+00:00" } ``` ### 4. 限流错误(429) ```bash curl -X POST "http://localhost:6170/api/v1/auth/sms/send" \ -H "Content-Type: application/json" \ -d '{"phone":"15980906230","countryCode":"+86","purpose":"login"}' ``` 响应: ```json { "success": false, "code": 429, "message": "今日发送次数已达上限", "data": null, "timestamp": "2026-01-27T08:21:32.130535+00:00" } ``` ## 影响范围 ### 受影响的异常类型 - `ValidationError` (400) - `AuthenticationError` (401) - `PermissionError` (403) - `NotFoundError` (404) - `InsufficientCreditsError` (402) - `RateLimitError` (429) - `RequestValidationError` (422) - 所有未捕获的异常 (500) ### 前端适配 前端现在可以统一处理所有 API 响应: ```typescript interface ApiResponse { success: boolean; code: number; message: string; data: T | null; timestamp: string; } // 统一错误处理 if (!response.success) { showError(response.message); } ``` ## 技术细节 ### 异常处理优先级 1. 特定状态码处理器(如 404) 2. HTTPException 处理器 3. RequestValidationError 处理器 4. 通用 Exception 处理器 ### 日志记录 - 500 错误会记录完整堆栈信息 - DEBUG 模式下返回详细错误信息 - 生产环境返回通用错误提示 ## 相关文档 - [RFC-135: 统一 API 响应格式](../rfcs/135-unified-api-response.md) - [API 响应规范](../../requirements/api-design-specification.md) ## 部署说明 无需数据库迁移,重启应用即可生效。 ## 后续优化 1. 添加错误码枚举,细化错误类型 2. 支持国际化错误消息 3. 添加错误追踪 ID(trace_id)