// 错误码 → 友好中文文案(+ 可选跳转动作)。 // 对齐后端 ErrorCode(ARCH §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 = { // 后端 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 }; }