type ClientErrorTone = "error" | "warning"; type ClientActionKind = "bind-account" | "open-console" | "probe-account" | "unbind-account"; interface ClientErrorPresentation { tone: ClientErrorTone; title: string; content: string; } const REMOTE_METHOD_PREFIX = /^Error invoking remote method '[^']+':\s*/i; const ERROR_PREFIX = /^Error:\s*/i; function rawErrorMessage(error: unknown): string { if (error instanceof Error) { return error.message; } if (typeof error === "string") { return error; } return ""; } export function unwrapClientErrorMessage(error: unknown, fallback: string): string { let message = rawErrorMessage(error).trim(); let previous = ""; while (message && message !== previous) { previous = message; message = message .replace(REMOTE_METHOD_PREFIX, "") .replace(ERROR_PREFIX, "") .trim(); } return message || fallback; } function presentClientError(kind: ClientActionKind, error: unknown): ClientErrorPresentation { const message = unwrapClientErrorMessage( error, kind === "bind-account" ? "账号绑定失败" : kind === "unbind-account" ? "账号解绑失败" : kind === "probe-account" ? "账号校验失败" : "打开平台失败", ); if (message === "desktop_account_bind_window_closed") { return { tone: "warning", title: "授权已中断", content: "授权窗口已关闭,本次绑定没有完成。重新点击“绑定账号”即可继续。", }; } if (message === "desktop_account_bind_limit_reached") { return { tone: "warning", title: "授权窗口已达上限", content: "当前最多同时打开 2 个授权窗口。请先完成或关闭已有授权窗口,再继续新的绑定。", }; } if (message === "desktop_account_upsert_failed") { return { tone: "error", title: "保存授权账号失败", content: "平台侧授权已经完成,但客户端回写账号信息失败。请稍后重试。", }; } if (message === "desktop_account_bind_failed") { return { tone: "error", title: "账号绑定失败", content: "授权流程执行失败,请稍后重新发起绑定。", }; } if (message.startsWith("desktop_platform_not_supported:")) { const platformId = message.split(":")[1] || "当前平台"; return { tone: "error", title: "平台暂不支持", content: `${platformId} 暂时还不支持这个操作。`, }; } if (message === "desktop_account_sync_conflict") { return { tone: "warning", title: kind === "unbind-account" ? "账号状态已变化" : "账号状态已更新", content: "当前账号状态刚刚发生了变化。请先刷新列表,再重试这次操作。", }; } if (message === "desktop_account_delete_failed") { return { tone: "error", title: "账号解绑失败", content: "服务端解绑没有成功完成,请稍后重试。", }; } if (kind === "open-console") { return { tone: "error", title: "打开平台失败", content: message, }; } if (kind === "probe-account") { return { tone: "error", title: "账号校验失败", content: message, }; } if (kind === "unbind-account") { return { tone: "error", title: "账号解绑失败", content: message, }; } return { tone: "error", title: "账号绑定失败", content: message, }; } export async function showClientActionError(kind: ClientActionKind, error: unknown): Promise { const presentation = presentClientError(kind, error); const { Modal } = await import("ant-design-vue"); const showModal = presentation.tone === "warning" ? Modal.warning : Modal.error; showModal({ title: presentation.title, content: presentation.content, okText: "知道了", centered: true, maskClosable: true, }); }