From 772081312e3709aaa67f67839365501111ed14de Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 9 Nov 2025 17:56:02 +0800 Subject: [PATCH] feat(ui): enhance provider switch error notification with copy action - Split error message into title and description for better UX - Add one-click copy button to easily share error details - Extend toast duration to 6s for improved readability - Use extractErrorMessage utility for consistent error handling - Add i18n keys: common.copy, notifications.switchFailedTitle This improves debugging experience when provider switching fails, allowing users to quickly copy and share error messages. --- src/i18n/locales/en.json | 6 ++++-- src/i18n/locales/zh.json | 6 ++++-- src/lib/query/mutations.ts | 22 ++++++++++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 5d9c0f0..2c57f1d 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -25,7 +25,8 @@ "toggleTheme": "Toggle theme", "format": "Format", "formatSuccess": "Formatted successfully", - "formatError": "Format failed: {{error}}" + "formatError": "Format failed: {{error}}", + "copy": "Copy" }, "apiKeyInput": { "placeholder": "Enter API Key", @@ -97,7 +98,8 @@ "providerSaved": "Provider configuration saved", "providerDeleted": "Provider deleted successfully", "switchSuccess": "Switch successful! Please restart {{appName}} terminal to take effect", - "switchFailed": "Switch failed, please check configuration", + "switchFailedTitle": "Switch failed", + "switchFailed": "Switch failed: {{error}}", "autoImported": "Default provider created from existing configuration", "addFailed": "Failed to add provider: {{error}}", "saveFailed": "Save failed: {{error}}", diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index 57f9286..7861699 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -25,7 +25,8 @@ "toggleTheme": "切换主题", "format": "格式化", "formatSuccess": "格式化成功", - "formatError": "格式化失败:{{error}}" + "formatError": "格式化失败:{{error}}", + "copy": "复制" }, "apiKeyInput": { "placeholder": "请输入API Key", @@ -97,7 +98,8 @@ "providerSaved": "供应商配置已保存", "providerDeleted": "供应商删除成功", "switchSuccess": "切换成功!请重启 {{appName}} 终端以生效", - "switchFailed": "切换失败,请检查配置", + "switchFailedTitle": "切换失败", + "switchFailed": "切换失败:{{error}}", "autoImported": "已从现有配置创建默认供应商", "addFailed": "添加供应商失败:{{error}}", "saveFailed": "保存失败:{{error}}", diff --git a/src/lib/query/mutations.ts b/src/lib/query/mutations.ts index cf88193..1013568 100644 --- a/src/lib/query/mutations.ts +++ b/src/lib/query/mutations.ts @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { providersApi, settingsApi, type AppId } from "@/lib/api"; import type { Provider, Settings } from "@/types"; +import { extractErrorMessage } from "@/utils/errorUtils"; export const useAddProviderMutation = (appId: AppId) => { const queryClient = useQueryClient(); @@ -143,11 +144,24 @@ export const useSwitchProviderMutation = (appId: AppId) => { ); }, onError: (error: Error) => { + const detail = extractErrorMessage(error) || t("common.unknown"); + + // 标题与详情分离,便于扫描 + 一键复制 toast.error( - t("notifications.switchFailed", { - defaultValue: "切换供应商失败: {{error}}", - error: error.message, - }), + t("notifications.switchFailedTitle", { defaultValue: "切换失败" }), + { + description: t("notifications.switchFailed", { + defaultValue: "切换失败:{{error}}", + error: detail, + }), + duration: 6000, + action: { + label: t("common.copy", { defaultValue: "复制" }), + onClick: () => { + navigator.clipboard?.writeText(detail).catch(() => undefined); + }, + }, + }, ); }, });