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

设计:全站 API 失败统一文案与 Toast 提示

日期:2026-04-18
状态:已定稿(与产品对话一致)

1. 背景与目标

当前 app/utils/http/factory.tsrequest 为裸 $fetch 实例;unwrapApiBodycode !== 0 时抛出带 messageError。HTTP 层失败表现为 ofetch 的 FetchError(常见字段含 statusMessagedata)。各页面仅在自行 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. 文案解析规则

按顺序取值,命中即停:

  1. 若对象为 FetchError 风格且 data 为对象且存在非空 message 字符串 → 使用该 message
  2. 若非空 statusMessage 字符串 → 使用。
  3. 若为 Errormessage 非空(含 unwrapApiBody 抛出的业务 message)→ 使用。
  4. 若存在 statusCode401 → 「登录已失效,请重新登录」;403 → 「没有权限执行此操作」;404 → 「请求的资源不存在」;5xx → 「服务暂时不可用,请稍后重试」。
  5. 无状态码或网络类失败 → 「网络异常,请检查连接后重试」或等价短句。
  6. 兜底 → 「请求失败,请稍后重试」。

(具体措辞可在实现时微调,但优先级与分支须一致,避免再次出现多种解析逻辑。)

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)。
  • 若调用方已有 catchtoast.add,应 删除 其中重复的错误 toast,仅保留特殊成功提示或额外上下文(否则会双弹)。
  • 保留 unwrapApiBodyApiResponse 类型;封装内部仍调用现有 request

7. 测试与验收

  • 手工:至少覆盖 — 登录失败(内联、无重复 toast)、管理端创建用户失败、评论失败、上传失败、任意 403/404 接口。
  • 自动化:若有 e2e,可增一条「失败时出现全局通知」;否则以回归清单为准。

8. 后续

定稿并实现后,由 writing-plans 产出 docs/superpowers/plans/2026-04-18-api-error-toast-implementation-plan.md(或同日合并命名),再进入编码。