# 前端统一错误响应格式适配 **日期**: 2026-01-27 **类型**: 功能增强 **影响范围**: API 客户端、类型定义 ## 变更概述 适配后端统一错误响应格式(RFC-135),更新前端 API 客户端和类型定义,确保前后端响应格式一致。 ## 问题背景 后端实现了统一响应格式: ```typescript { success: boolean; code: number; message: string; data: T | null; timestamp: string; } ``` 但前端类型定义和响应拦截器仍使用旧格式,缺少 `success` 和 `timestamp` 字段。 ## 解决方案 ### 1. 更新 API 响应类型定义 **文件**: `client/src/types/api.ts` ```typescript // 旧格式 export interface ApiResponse { code: number; message: string; data: T; } // 新格式 export interface ApiResponse { success: boolean; // ✅ 新增 code: number; message: string; data: T | null; // ✅ 支持 null timestamp: string; // ✅ 新增 } ``` ### 2. 更新响应拦截器 **文件**: `client/src/services/api/client.ts` #### 成功响应处理 ```typescript // 优先检查新格式(success 字段) if (res && typeof res === 'object' && typeof res.success === 'boolean') { if (res.success) { return res.data; } // 业务错误 const message = res.message || 'Unknown Error'; const error = new Error(message); (error as any).code = res.code; (error as any).data = res.data; return Promise.reject(error); } // 兼容旧格式(code 字段) if (res && typeof res === 'object' && typeof res.code === 'number') { if (res.code === 200) { return res.data; } // ... } ``` #### 错误响应处理 ```typescript // 处理统一错误响应格式 const errorData = error.response?.data as any; if (errorData && typeof errorData.success === 'boolean' && !errorData.success) { const message = errorData.message || 'Unknown Error'; const customError = new Error(message); (customError as any).code = errorData.code; (customError as any).data = errorData.data; (customError as any).timestamp = errorData.timestamp; // 401/403 认证错误特殊处理 if (errorData.code === 401 || errorData.code === 403) { useAppStore.getState().setUser(null); localStorage.removeItem('token'); window.location.href = '/login'; } return Promise.reject(customError); } ``` ## 兼容性 ### 向后兼容 响应拦截器同时支持新旧两种格式: 1. **新格式**(优先):检查 `success` 字段 2. **旧格式**(兼容):检查 `code === 200` 这确保了在后端逐步迁移期间,前端不会出现问题。 ### 错误对象增强 错误对象现在包含更多信息: ```typescript interface CustomError extends Error { code: number; // HTTP 状态码 data: any; // 错误详情 timestamp?: string; // 错误时间戳 } ``` ## 测试场景 ### 1. 成功响应 ```typescript // 后端返回 { "success": true, "code": 200, "message": "Success", "data": { "userId": "123" }, "timestamp": "2026-01-27T08:00:00Z" } // 前端接收 { "userId": "123" } // 自动提取 data ``` ### 2. 业务错误(400) ```typescript // 后端返回 { "success": false, "code": 400, "message": "验证码错误", "data": null, "timestamp": "2026-01-27T08:00:00Z" } // 前端捕获 catch (error) { console.error(error.message); // "验证码错误" console.error(error.code); // 400 } ``` ### 3. 参数验证错误(422) ```typescript // 后端返回 { "success": false, "code": 422, "message": "body -> code: Field required", "data": { "errors": [...] }, "timestamp": "2026-01-27T08:00:00Z" } // 前端捕获 catch (error) { console.error(error.message); // "body -> code: Field required" console.error(error.data); // { "errors": [...] } } ``` ### 4. 认证错误(401) ```typescript // 后端返回 { "success": false, "code": 401, "message": "认证失败", "data": null, "timestamp": "2026-01-27T08:00:00Z" } // 前端行为 // 1. 清除用户状态 // 2. 删除 token // 3. 跳转登录页 ``` ## 使用示例 ### API 调用 ```typescript import apiClient from '@/services/api/client'; // 成功场景 try { const user = await apiClient.get('/api/v1/users/me'); console.log(user); // 直接获取 data } catch (error) { console.error(error.message); // 统一错误消息 console.error(error.code); // HTTP 状态码 } // 错误场景 try { await apiClient.post('/api/v1/auth/login/phone', { phone: '18046315592', code: '000000' }); } catch (error) { // error.message: "验证码错误" // error.code: 400 showToast(error.message); } ``` ### 类型安全 ```typescript import type { ApiResponse } from '@/types/api'; // 完整响应类型 const response: ApiResponse = { success: true, code: 200, message: 'Success', data: { userId: '123', username: 'test' }, timestamp: '2026-01-27T08:00:00Z' }; // data 可以为 null const errorResponse: ApiResponse = { success: false, code: 400, message: 'Error', data: null, timestamp: '2026-01-27T08:00:00Z' }; ``` ## 影响范围 ### 受影响文件 - `client/src/types/api.ts` - 类型定义 - `client/src/services/api/client.ts` - 响应拦截器 ### 不受影响 - 所有使用 `apiClient` 的业务代码无需修改 - 响应拦截器自动处理格式转换 - 错误处理逻辑保持不变 ## 相关文档 - [后端统一错误响应实现](../../server/changelogs/2026-01-27-unified-error-response.md) - [RFC-135: 统一 API 响应格式](../../server/rfcs/135-unified-api-response.md) - [ADR-005: 统一 API 响应处理](../adrs/005-unified-api-response-handling.md) ## 部署说明 无需特殊部署步骤,前端构建后即可生效。 ## 后续优化 1. 添加响应时间监控(利用 `timestamp` 字段) 2. 实现错误重试机制(基于 `code` 判断) 3. 统一错误提示组件(显示 `message`) 4. 添加错误追踪(记录 `timestamp` 和 `code`)