2026-07-09 11:16:59 +08:00
|
|
|
|
---
|
|
|
|
|
|
kind: error_handling
|
|
|
|
|
|
name: 全栈错误处理与响应规范
|
|
|
|
|
|
category: error_handling
|
|
|
|
|
|
scope:
|
|
|
|
|
|
- '**'
|
|
|
|
|
|
source_files:
|
|
|
|
|
|
- backend/src/utils/response.js
|
|
|
|
|
|
- backend/src/app.js
|
|
|
|
|
|
- backend/src/middleware/auth.js
|
|
|
|
|
|
- backend/src/routes/models.js
|
|
|
|
|
|
- backend/src/routes/auth.js
|
|
|
|
|
|
- frontend/src/utils/request.js
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-06-30 14:46:52 +08:00
|
|
|
|
### 1. 核心策略:统一响应结构与业务码
|
|
|
|
|
|
该仓库采用**基于 HTTP 200 的业务状态码**模式,而非依赖 HTTP 协议层的状态码来区分业务逻辑的成功与失败。
|
|
|
|
|
|
|
|
|
|
|
|
- **后端 (Node.js/Express)**:
|
|
|
|
|
|
- 所有接口(除认证中间件外)均返回 `HTTP 200`。
|
|
|
|
|
|
- 通过 `ApiResponse` 工具类封装响应体,包含 `code`、`msg` 和 `data` 字段。
|
|
|
|
|
|
- **成功**:`code: 1`。
|
|
|
|
|
|
- **失败**:`code: 0`(通用错误)或 `code: 2`(无数据)。
|
|
|
|
|
|
- **异常捕获**:在路由层使用 `try...catch` 包裹异步逻辑,捕获异常后记录日志并返回 `ApiResponse.error()`。
|
|
|
|
|
|
|
|
|
|
|
|
- **前端 (Vue 3/Axios)**:
|
|
|
|
|
|
- 在 `request.js` 中配置响应拦截器。
|
|
|
|
|
|
- 当检测到 `res.code === 0` 时,自动触发 `ElMessage.error` 提示用户,并将 Promise 标记为 `reject`。
|
|
|
|
|
|
- 支持 `skipErrorToast` 配置项,允许特定请求(如进度轮询)静默处理错误。
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 关键文件与实现细节
|
|
|
|
|
|
|
|
|
|
|
|
#### 后端:响应工具与中间件
|
|
|
|
|
|
- **`backend/src/utils/response.js`**:定义了全局统一的响应格式。`ApiResponse.success`、`ApiResponse.error` 和 `ApiResponse.noData` 是后端返回数据的唯一出口。
|
|
|
|
|
|
- **`backend/src/middleware/auth.js`**:**例外情况**。认证中间件直接操作 `res.status(401)` 或 `res.status(403)`。这是为了在前端拦截器中能准确识别身份失效并执行重定向逻辑。
|
|
|
|
|
|
- **`backend/src/routes/*.js`**:各业务路由文件(如 `models.js`, `auth.js`)遵循“捕获即返回”原则。例如在 `models.js` 中,数据库查询或 S3 上传失败均被捕获并转换为友好的中文错误提示。
|
|
|
|
|
|
|
|
|
|
|
|
#### 前端:拦截器与权限联动
|
|
|
|
|
|
- **`frontend/src/utils/request.js`**:
|
|
|
|
|
|
- **401 处理**:自动清除本地 Token (`clearAuth`) 并重定向至登录页。
|
|
|
|
|
|
- **403 处理**:弹出“无权限”警告。
|
|
|
|
|
|
- **网络错误**:捕获非业务逻辑的网络层异常(如超时、断网),统一提示“网络错误”。
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 架构约定与开发规则
|
|
|
|
|
|
1. **禁止直接抛出未捕获异常**:后端路由处理器必须包含 `try...catch` 块,确保任何内部错误(DB、S3、Meilisearch)都不会导致进程崩溃或返回原始堆栈信息。
|
|
|
|
|
|
|
|
|
|
|
|
2. **敏感信息脱敏**:在 `catch` 块中返回给前端的 `msg` 应为通用提示(如“error”或“登录失败”),具体错误详情仅通过 `logger.error` 记录在服务器日志中。
|
|
|
|
|
|
|
|
|
|
|
|
3. **前端错误消费**:
|
|
|
|
|
|
- 默认情况下,前端无需在每个 API 调用处编写 `catch` 逻辑来处理 UI 提示,拦截器已自动完成。
|
|
|
|
|
|
- 若需自定义错误处理(如表单校验反馈),应在 API 调用处捕获 `Promise.reject` 并阻止默认弹窗。
|
|
|
|
|
|
|
|
|
|
|
|
4. **认证优先原则**:涉及权限的接口,先由中间件进行 Token 校验。若校验失败,直接中断请求链路并返回标准 HTTP 401/403,不进入业务逻辑层的 `try...catch`。
|