Files
writer-work-flow/apps/web/lib/errors/messages.ts
Yaojia Wang b18310bcb7 feat(ux): F3 流式进度感 + F4 友好错误文案(纯前端)
F4:新 lib/errors/messages.ts —— friendlyError(code, fallback) 把错误码映射为
中文文案 + 可选「去设置提供商」动作;覆盖后端 ErrorCode + 前端 NETWORK/
STREAM_FAILED;未知码回退原 message。写作页与审稿页错误块改用之,不再暴露
raw error code。+4 vitest。

F3:写作页工具条字数计数器流式时显示「生成中… N 字」+ 朱砂脉冲
(motion-safe:animate-pulse,尊重 prefers-reduced-motion),停后回「字数 N」。
纯 text.length,无后端改动。

前端门禁绿:lint/typecheck/vitest 171/build。无契约变更。
2026-06-20 11:02:27 +02:00

47 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 错误码 → 友好中文文案(+ 可选跳转动作)。
// 对齐后端 ErrorCodeARCH §7.1+ 前端流式/网络码useDraftStream
// 目的UI 不直接暴露 error code给作者可读的下一步。
export interface FriendlyError {
text: string;
// 可选的「下一步」链接(如未连模型 → 去设置)。
actionHref?: string;
actionLabel?: string;
}
const PROVIDER_ACTION = {
actionHref: "/settings/providers",
actionLabel: "去设置提供商",
} as const;
const MESSAGES: Record<string, FriendlyError> = {
// 后端 ErrorCode
LLM_UNAVAILABLE: {
text: "未连接可用模型,去设置里连一个 provider。",
...PROVIDER_ACTION,
},
RATE_LIMITED: { text: "请求过于频繁,稍后再试。" },
CONFLICT_UNRESOLVED: { text: "仍有未裁决的冲突,请先逐条裁决再验收。" },
NOT_FOUND: { text: "资源不存在或已被删除。" },
VALIDATION: { text: "提交内容有误,请检查后重试。" },
INTERNAL: { text: "服务出了点问题,请稍后重试。" },
// 前端流式/网络码
NETWORK: { text: "网络中断,请检查连接后重试。" },
STREAM_FAILED: { text: "写章中断,请重试。" },
};
const DEFAULT_TEXT = "出错了,请稍后重试。";
// 把 (code, 原始 message) 映射为友好文案。
// 已知码 → 预设文案 + 动作;未知码 → 回退到原始 message非空或通用兜底。
export function friendlyError(
code: string | undefined,
fallbackMessage?: string,
): FriendlyError {
if (code && MESSAGES[code]) {
return MESSAGES[code];
}
const fallback = fallbackMessage?.trim();
return { text: fallback && fallback.length > 0 ? fallback : DEFAULT_TEXT };
}