外观
错误码与鉴权
错误码文档统一前后端对失败的理解,避免业务 4xx 被包装成网络错误。后端大多数接口直接抛 HTTPException(detail=...);Flutter client 需要优先读取 detail,再使用本地 fallback 文案。
鉴权机制
| 项 | 当前实现 |
|---|---|
| Header | Authorization: Bearer <jwt> |
| 解析位置 | apps/backend_service/app/api/auth_dependencies.py:get_current_user |
| JWT payload | 必须包含 user_id |
| 用户校验 | 后端根据 user_id 查询 users;不存在则返回 401 |
| 失败 header | WWW-Authenticate: Bearer |
通用错误码
| Status | 后端含义 | 常见来源 | 前端处理口径 |
|---|---|---|---|
400 | 业务参数不合法或状态不允许 | 验证码错误、处方 duration 越界、日期范围非法、头像 object key 非法 | 展示 detail;可由用户修改输入后重试。 |
401 | 缺失、无效或过期 JWT;用户不存在 | get_current_user、密码登录失败 | 清理本地登录态,引导重新登录;不要当作普通网络失败。 |
403 | 资源存在但不属于当前用户 | 运动记录、用户方案、数据一致性检查 | 展示权限提示;停止继续请求该资源。 |
404 | 资源不存在、已删除或无权限暴露为不存在 | chat session、sport log、companion status、disease/operation | 对详情页展示不存在;对 active sport log 可解释为无进行中运动。 |
409 | 业务冲突 | 创建未完成运动时已有 active log | 提示先完成当前运动,再创建新运动。 |
422 | Pydantic 请求结构或字段格式失败 | 手机号、日期、枚举、必填字段 | 字段级提示;开发联调时检查 JSON key 与 alias。 |
429 | 频率限制 | 短信验证码发送 | 提示稍后再试,不自动高频重试。 |
500 | 服务端异常或外部依赖失败 | LLM/RAG、短信、DB、文件存储、未知异常 | 展示可恢复失败;允许用户稍后重试;日志侧定位。 |
模块差异
| 模块 | 需要特别处理的错误 |
|---|---|
| Auth | send-sms 的 429 是用户可恢复状态;密码登录 401 表示认证失败。 |
| User | 400/413/415/422 多为头像或字段校验;UserApiClient 已优先读取 detail。 |
| Chat | sessionId 非本人或不存在返回 404;idempotencyKey 命中返回 200 重放响应。 |
| Prescription | 生成链路可能耗时较长;Flutter 已把生成请求 receive timeout 提高到 120 秒。 |
| Sport | POST /log 在已有进行中运动时返回 409;GET /active 的 404 是正常空状态。 |
| Assessment | safety_check 持久化失败只记录 warning,不阻断主响应。 |
| Safety | 当前多数失败统一为 500 服务暂不可用;事件报告写入 safety_incidents 脱敏审计记录。 |
| Companion | debug route 生产不注册;生产误调 /test 会得到 404。 |
前端错误处理锚点
| Client | 当前处理特点 |
|---|---|
AuthApiClient | 对 400/429/500 做模块文案映射。 |
UserApiClient | 读取 detail,区分 401、字段类 4xx、5xx、网络超时。 |
ChatApiClient | bad response 当前优先读 message,而后端多用 detail;联调时需要注意文案可能退回通用 “请求失败”。 |
SportApiClient | 区分 401/403/404/500,MET 获取失败会使用本地默认值。 |
PrescriptionApiClient | 使用 ErrorHandler 归一错误;当前处方 404/204 会视为无处方。 |
CompanionApiClient | 多数错误返回 fallback companion/health overview,不直接抛出。 |
AssessmentApiClient | 非 200 多数直接抛包含 response body 的异常。 |
来源锚点
- Auth dependency:
apps/backend_service/app/api/auth_dependencies.py - Routers:
apps/backend_service/app/api/ - Flutter clients:
apps/flutter_app/lib/api/ - Error helper:
apps/flutter_app/lib/utils/error_handler.dart - Tests:
apps/backend_service/tests/api/test_auth_dependency.py、apps/flutter_app/test/utils/error_handler_test.dart