You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.3 KiB
4.3 KiB
设计:全站 API 失败统一文案与 Toast 提示
日期:2026-04-18
状态:已定稿(与产品对话一致)
1. 背景与目标
当前 app/utils/http/factory.ts 中 request 为裸 $fetch 实例;unwrapApiBody 在 code !== 0 时抛出带 message 的 Error。HTTP 层失败表现为 ofetch 的 FetchError(常见字段含 statusMessage、data)。各页面仅在自行 catch 时才会 useToast(),导致部分操作失败时 无可见反馈,且多处重复手写 extractError,同一类失败文案不一致。
目标:
- 用户触发的 API 调用失败时,默认有一条 可读中文 toast(Nuxt UI
useToast)。 - 文案优先来自服务端已有
statusMessage/ 业务message,避免空白或仅控制台错误。 - 单一实现 解析
unknown错误为展示字符串,收敛重复代码。
2. 非目标
- 在 SSR 阶段弹出 toast(仅客户端展示)。
- 替代表单字段级校验(组件内仍可保留短提示)。
- 本次不强制改造
_useHttpFetch/ 声明式useFetch用法(可作为后续增量)。 - 不改变服务端错误契约(仍用
createError+ApiResponse等现有形态)。
3. 方案结论(已选)
采用 薄封装 + 统一解析(否决全局 $fetch 钩子自动 toast:难以区分静默场景、与 useAuthSession 等冲突)。
| 构件 | 职责 |
|---|---|
getApiErrorMessage(error: unknown): string |
单一模块,统一从 Error / FetchError 等解析用户可见文案。 |
useClientApi()(命名以实现为准) |
返回与 request 兼容的调用方法;默认在客户端失败时 toast.add(error)后 原样 rethrow,保证调用方 finally、状态回滚仍可用。 |
选项 notify: false |
关闭本次请求的 toast(会话刷新、401 静默路径、登录页内联错误、自定义多段流程等)。 |
4. 文案解析规则
按顺序取值,命中即停:
- 若对象为 FetchError 风格且
data为对象且存在非空message字符串 → 使用该message。 - 若非空
statusMessage字符串 → 使用。 - 若为
Error且message非空(含unwrapApiBody抛出的业务message)→ 使用。 - 若存在
statusCode:401 → 「登录已失效,请重新登录」;403 → 「没有权限执行此操作」;404 → 「请求的资源不存在」;5xx → 「服务暂时不可用,请稍后重试」。 - 无状态码或网络类失败 → 「网络异常,请检查连接后重试」或等价短句。
- 兜底 → 「请求失败,请稍后重试」。
(具体措辞可在实现时微调,但优先级与分支须一致,避免再次出现多种解析逻辑。)
5. 401 与认证路径(已确认策略)
useAuthSession.refresh/ 通过useRequestFetch拉/api/auth/me的路径:保持现有行为 — 不因 401 弹业务 toast(notify: false或继续使用裸request/ 现有catch逻辑);401 时清会话等逻辑不变。- 其余用户触发的客户端 API:默认
notify: true;若响应为 401,用户看到 一条与第 4 节一致的短文案(与「静默清会话」可并存:先 toast,路由或后续导航由现有布局/中间件处理)。 - 登录 / 注册页:失败提示以 表单内联 为主;对应请求使用
notify: false,避免与内联文案重复。
6. 迁移与重复 toast 防护
- 将
app/pages/**、app/components/**中 面向用户的request(...)逐步改为封装方法(默认notify: true)。 - 若调用方已有
catch且toast.add,应 删除 其中重复的错误 toast,仅保留特殊成功提示或额外上下文(否则会双弹)。 - 保留
unwrapApiBody与ApiResponse类型;封装内部仍调用现有request。
7. 测试与验收
- 手工:至少覆盖 — 登录失败(内联、无重复 toast)、管理端创建用户失败、评论失败、上传失败、任意 403/404 接口。
- 自动化:若有 e2e,可增一条「失败时出现全局通知」;否则以回归清单为准。
8. 后续
定稿并实现后,由 writing-plans 产出 docs/superpowers/plans/2026-04-18-api-error-toast-implementation-plan.md(或同日合并命名),再进入编码。