返回 DeepSeek-Reasonix
inboxError.ts
根目录 / desktop / frontend / src / lib / inboxError.ts
1 import type { Locale } from "./i18n";
2
3 const CODE_PREFIX = "reasonix_error:";
4
5 // Message arrays share one stable code-to-index table so the three localized
6 // copies do not repeat object keys in the initial desktop bundle.
7 const CODE_INDEX = {
8 inbox_paused: 0,
9 inbox_capacity_items: 1,
10 inbox_capacity_bytes: 2,
11 inbox_item_too_large: 3,
12 inbox_item_not_found: 4,
13 inbox_invalid_state: 5,
14 inbox_schema_readonly: 6,
15 inbox_closed: 7,
16 inbox_empty: 8,
17 inbox_idempotency_conflict: 9,
18 channel_read_only: 10,
19 workspace_starting: 11,
20 workspace_start_failed: 12,
21 inbox_not_submitted: 16,
22 image_attachment_unreadable: 17,
23 } as const;
24
25 type InboxErrorCode = keyof typeof CODE_INDEX;
26 const UNKNOWN_INDEX = 13;
27 const STEER_QUEUED_INDEX = 14;
28 const CANCEL_FAILED_INDEX = 15;
29
30 const ERROR_COPY: Record<Locale, readonly string[]> = {
31 en: [
32 "Inbox is paused",
33 "The inbox has reached its item limit",
34 "The inbox has reached its storage limit",
35 "This instruction is too large to add to the inbox",
36 "This inbox instruction no longer exists",
37 "This inbox instruction cannot be changed in its current state",
38 "This inbox was created by a newer version and is read-only",
39 "The inbox is closed",
40 "A blank instruction cannot be added",
41 "This instruction conflicts with an earlier submission",
42 "This session is read-only, so its inbox cannot be changed",
43 "The workspace is still starting. Try again shortly",
44 "The workspace failed to start",
45 "The inbox operation could not be completed",
46 "The turn ended before guidance could be applied. It will remain queued for the next turn",
47 "Cancel failed: {error}",
48 "The message was not sent. Refresh the session and try again",
49 "The image could not be read. Re-add it or try again",
50 ],
51 zh: [
52 "收件箱已暂停",
53 "收件箱已达到条目上限",
54 "收件箱已达到容量上限",
55 "这条指令太大,无法加入收件箱",
56 "这条收件箱指令已不存在",
57 "当前状态下无法操作这条收件箱指令",
58 "收件箱由较新版本创建,当前只能读取",
59 "收件箱已关闭",
60 "不能加入空白指令",
61 "这条指令与已提交的请求冲突",
62 "当前会话为只读,无法修改收件箱",
63 "工作区还在启动,请稍后重试",
64 "工作区启动失败",
65 "无法完成收件箱操作",
66 "引导尚未应用时当前回合已结束;它会保留在队列中,供下一回合处理",
67 "取消失败:{error}",
68 "消息未发送,请刷新会话后重试",
69 "图片读取失败,请重新添加或重试",
70 ],
71 "zh-TW": [
72 "收件匣已暫停",
73 "收件匣已達到項目上限",
74 "收件匣已達到容量上限",
75 "這條指令太大,無法加入收件匣",
76 "這條收件匣指令已不存在",
77 "目前狀態下無法操作這條收件匣指令",
78 "收件匣由較新版本建立,目前只能讀取",
79 "收件匣已關閉",
80 "不能加入空白指令",
81 "這條指令與已提交的請求衝突",
82 "目前會話為唯讀,無法修改收件匣",
83 "工作區還在啟動,請稍後重試",
84 "工作區啟動失敗",
85 "無法完成收件匣操作",
86 "引導尚未套用時目前回合已結束;它會保留在佇列中,供下一回合處理",
87 "取消失敗:{error}",
88 "訊息未傳送,請重新整理會話後重試",
89 "圖片讀取失敗,請重新加入或重試",
90 ],
91 };
92
93 const LEGACY_CODES: Record<string, InboxErrorCode> = {
94 "inbox is paused": "inbox_paused",
95 "session inbox item limit reached": "inbox_capacity_items",
96 "session inbox byte limit reached": "inbox_capacity_bytes",
97 "inbox item exceeds single-item size limit": "inbox_item_too_large",
98 "inbox item not found": "inbox_item_not_found",
99 "inbox item state does not allow this operation": "inbox_invalid_state",
100 "inbox schema is newer and is read-only": "inbox_schema_readonly",
101 "inbox is closed": "inbox_closed",
102 "inbox item body is empty": "inbox_empty",
103 "idempotency key was already used for different input": "inbox_idempotency_conflict",
104 "channel session is read-only": "channel_read_only",
105 "workspace is still starting": "workspace_starting",
106 };
107
108 function errorText(error: unknown): string {
109 return error instanceof Error ? error.message : String(error);
110 }
111
112 export function formatInboxError(error: unknown, locale: Locale): string {
113 const raw = errorText(error);
114 const encodedCode = raw.startsWith(CODE_PREFIX) ? raw.slice(CODE_PREFIX.length) : "";
115 const legacyCode = LEGACY_CODES[raw]
116 ?? (raw.startsWith("workspace failed to start:") ? "workspace_start_failed" : undefined);
117 const code = encodedCode || legacyCode;
118 if (!code) return raw;
119 const index = CODE_INDEX[code as InboxErrorCode];
120 return ERROR_COPY[locale][index ?? UNKNOWN_INDEX];
121 }
122
123 export function inboxSteerQueuedMessage(locale: Locale): string {
124 return ERROR_COPY[locale][STEER_QUEUED_INDEX];
125 }
126
127 export function isInboxItemMissing(error: unknown): boolean {
128 const raw = errorText(error);
129 return raw === `${CODE_PREFIX}inbox_item_not_found` || raw === "inbox item not found";
130 }
131
132 // The idle-tab code is consumed by the Stop path, never displayed.
133 export function isTurnNotRunning(error: unknown): boolean {
134 return errorText(error) === `${CODE_PREFIX}turn_not_running`;
135 }
136
137 export function formatInboxCancelError(error: unknown, locale: Locale): string {
138 return ERROR_COPY[locale][CANCEL_FAILED_INDEX].replace("{error}", formatInboxError(error, locale));
139 }
140
140 lines TYPESCRIPT