Skip to content

fix(desktop): localize update fetch-failure message on Windows#1088

Open
teddyli18000 wants to merge 1 commit intonexu-io:mainfrom
teddyli18000:fix/994-windows-update-i18n
Open

fix(desktop): localize update fetch-failure message on Windows#1088
teddyli18000 wants to merge 1 commit intonexu-io:mainfrom
teddyli18000:fix/994-windows-update-i18n

Conversation

@teddyli18000
Copy link
Copy Markdown

@teddyli18000 teddyli18000 commented Apr 14, 2026

What

Normalize update fetch/network failure errors in the desktop renderer so Chinese users no longer see the raw English string fetch failed in update failure notifications.

Why

Closes #994.

On Windows with zh-CN UI, update failures could surface as mixed-language notifications (更新失败 with raw fetch failed detail), which is confusing and breaks localization consistency.

How

  • Exported normalizeUpdateErrorMessage from the update hook for direct regression testing.
  • Added a dedicated normalization branch for fetch-related failures:
    • fetch failed
    • failed to fetch
    • NetworkError ... fetch
  • Mapped these errors to user-friendly localized messages:
    • EN: Network connection failed while checking for updates. Check your connection and try again.
    • ZH: 网络连接失败,请检查网络后重试。
  • Added regression tests for both normal and local-test-feed update experiences.

Affected areas

  • Desktop app (Electron shell)
  • Controller (backend / API)
  • Web dashboard (React UI)
  • OpenClaw runtime
  • Skills
  • Shared schemas / packages
  • Build / CI / Tooling

Checklist

  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes
  • pnpm generate-types run (if API routes/schemas changed)
  • No credentials or tokens in code or logs
  • No any types introduced (use unknown with narrowing)

Screenshots / recordings

  • Reproduction:

  • pr 994 reproduction
  • Fixed:

pr 994 fixed

Notes for reviewers

  • Core code change: apps/desktop/src/hooks/use-auto-update.ts
  • Regression tests: tests/desktop/update-error-message-normalization.test.ts
  • Focus manual verification on update error banner text under zh-CN when update check fails due to network/feed failures.

Copilot AI review requested due to automatic review settings April 14, 2026 05:44
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a desktop i18n UX issue on Windows by normalizing fetch/network-related auto-update errors so localized UIs (notably zh-CN) don’t surface the raw English "fetch failed" string in update failure notifications.

Changes:

  • Exported normalizeUpdateErrorMessage from the desktop auto-update hook to enable direct regression testing.
  • Added normalization for fetch-related failure messages (fetch failed, failed to fetch, NetworkError ... fetch) mapping them to localized, user-friendly strings.
  • Added Vitest regression tests covering both normal updates and local-test-feed update experiences.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
apps/desktop/src/hooks/use-auto-update.ts Exposes and extends update error normalization to localize fetch/network failures.
tests/desktop/update-error-message-normalization.test.ts Adds regression tests ensuring fetch-failure messages are normalized in both update experiences.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +4 to +16
describe("update error message normalization", () => {
it("normalizes fetch failures in normal update mode", () => {
const result = normalizeUpdateErrorMessage("fetch failed", "normal");
expect(result).not.toMatch(/fetch failed/i);
});

it("normalizes fetch failures in local test feed mode", () => {
const result = normalizeUpdateErrorMessage(
"TypeError: fetch failed",
"local-test-feed",
);
expect(result).not.toMatch(/fetch failed/i);
});
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions only check that the output no longer contains the substring "fetch failed", which would still pass if the function returns a different raw English fetch-related message (e.g., "NetworkError when attempting to fetch…") or an empty/placeholder string. Consider asserting the exact expected normalized message (or a stable key phrase), and explicitly controlling the locale (e.g., temporarily set/define navigator.language to en-US and zh-CN) so the test validates the localized output deterministically.

Suggested change
describe("update error message normalization", () => {
it("normalizes fetch failures in normal update mode", () => {
const result = normalizeUpdateErrorMessage("fetch failed", "normal");
expect(result).not.toMatch(/fetch failed/i);
});
it("normalizes fetch failures in local test feed mode", () => {
const result = normalizeUpdateErrorMessage(
"TypeError: fetch failed",
"local-test-feed",
);
expect(result).not.toMatch(/fetch failed/i);
});
const withNavigatorLanguage = <T>(language: string, run: () => T): T => {
const originalDescriptor = Object.getOwnPropertyDescriptor(
window.navigator,
"language",
);
Object.defineProperty(window.navigator, "language", {
configurable: true,
value: language,
});
try {
return run();
} finally {
if (originalDescriptor) {
Object.defineProperty(window.navigator, "language", originalDescriptor);
} else {
delete (window.navigator as Navigator & { language?: string }).language;
}
}
};
describe("update error message normalization", () => {
it("normalizes fetch failures in normal update mode for en-US", () => {
const result = withNavigatorLanguage("en-US", () =>
normalizeUpdateErrorMessage("fetch failed", "normal"),
);
expect(result).toContain("network");
expect(result).not.toMatch(/fetch failed/i);
});
it("normalizes fetch failures in normal update mode for zh-CN", () => {
const result = withNavigatorLanguage("zh-CN", () =>
normalizeUpdateErrorMessage("fetch failed", "normal"),
);
expect(result).toContain("网络");
expect(result).not.toMatch(/fetch failed/i);
});
it("normalizes fetch failures in local test feed mode for en-US", () => {
const result = withNavigatorLanguage("en-US", () =>
normalizeUpdateErrorMessage("TypeError: fetch failed", "local-test-feed"),
);
expect(result).toContain("local");
expect(result).toContain("server");
expect(result).not.toMatch(/fetch failed/i);
});
it("normalizes fetch failures in local test feed mode for zh-CN", () => {
const result = withNavigatorLanguage("zh-CN", () =>
normalizeUpdateErrorMessage("TypeError: fetch failed", "local-test-feed"),
);
expect(result).toContain("本地");
expect(result).toContain("服务器");
expect(result).not.toMatch(/fetch failed/i);
});

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
it("normalizes fetch failures in local test feed mode", () => {
const result = normalizeUpdateErrorMessage(
"TypeError: fetch failed",
"local-test-feed",
);
expect(result).not.toMatch(/fetch failed/i);
});
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test also only asserts that "fetch failed" is absent; it doesn't verify the actual user-facing string for the local-test-feed experience or that the output is localized under a zh locale. Strengthen it by forcing the locale and asserting the expected normalized message for both normal and local-test-feed inputs.

Copilot uses AI. Check for mistakes.
@sentry
Copy link
Copy Markdown

sentry bot commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
apps/desktop/src/hooks/use-auto-update.ts 88.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@caiqiling958-cmd
Copy link
Copy Markdown
Contributor

@teddyli18000 👋你好呀~ 我们收到您今天提交了 2 次 Pr,我们非常感激你的贡献 🎉
我会在 24 小时内完成 Review,如果有需要修改或优化的地方,会在这里留言说明。 如果过程中有任何问题,随时可以沟通。另外,我们有一个 Nexu 开发者飞书交流群,加入可以更快获得反馈,也能和其他贡献者一起交流,也方便我们给您提供更多的支持和帮助。
nexu 开发者飞书交流群 👇
https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=054u93b4-f45e-4849-92d4-96a4d4a90d03

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Windows][i18n] Update failure message mixes Chinese and English ("fetch failed")

3 participants