Skip to content

fix(ui): translate the remaining user-visible backend errors in English mode - #165

Merged
argszero merged 1 commit into
mainfrom
fix/err-map-coverage
Sep 11, 2026
Merged

argszero merged 1 commit into
mainfrom
fix/err-map-coverage

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

ERR_MAP in ui/js/i18n.js maps the backend's Chinese error strings to English translation keys. Several messages returned on paths a user can actually reach were never wired into it, so English-mode users saw raw Chinese.

The clearest case is an orphaned key: err.network is defined in both packs, and its Chinese value is exactly the literal api.js passes to mapErr on a network failure (ui/js/api.js:66) — but no ERR_MAP entry referenced it. The translation existed and was unreachable:

EN user, network failure — before: "网络不可用,请检查后端服务是否启动"
EN user, network failure — after : "Network unavailable, please check if the backend service is running"

Covered in this PR, each on a path the console actually calls:

key literal source
err.network (key already existed) 网络不可用,请检查后端服务是否启动 api.js:66 network failure
err.emailNotRegistered 该邮箱未注册 auth/reset_password (src/routes/mod.rs:388) — forgot-password form
err.raisePending 已有待审批的加额申请,请等待管理员处理 raise_requests/create
err.raiseHandled 该申请已处理 raise_requests approve/reject
err.codeSendFail 验证码发送失败,请重试 auth/login 502
err.modelExists 模型已存在(provider+model 唯一) admin/models create/patch
err.negativePrice 价格不能为负数 admin/models create/patch

Six new keys were added to both packs (769 → 775, ZH == EN); err.network already existed and only needed wiring. Coverage of the 40 production backend error strings goes from 18 → 24.

Related Issue

Changes

Tests

  • cargo test — 148 passed; 0 failed
  • cargo fmt --check — clean
  • cargo clippy --all-targets -- -D warnings — clean
  • node --check on all four ui/js/*.js — clean
  • Key parity verified on the evaluated module (not a regex over source): 775 == 775, no duplicates, no one-sided keys

Behavioural verification (no JS test runner exists in this repo — its convention is Rust #[cfg(test)] and CI runs fmt/clippy/test only, so none was added):

  • Compared against the true pre-fix baseline taken from git show HEAD:ui/js/i18n.js, replaying every real message through the real mapErr in EN mode: exactly 7 messages change, all from raw Chinese to English, 0 regressions. (err.network is a single merged entry covering two sources, so it counts once — hence 7 changed vs 7 cases listed above.)
  • Controls: zh-mode passthrough ✅, unmatched-message passthrough ✅, null passthrough ✅, and a previously-wired key still translating ✅.
  • Spot-checked that unchanged messages are still English (点数余额不足, 该邮箱已注册, 模型不存在, 验证码错误).

Checklist

  • Branch naming follows the convention (fix/<description>)
  • Commit message uses Conventional Commits (fix(ui): …)
  • Single responsibility, minimal diff (2 files, +24/−5)

Deliberately NOT covered

To keep this honest rather than exhaustive, the remaining unmapped strings are defensive validation on URLs/states the console never generates — wallet type 必须为… / ISO-8601 params, sharing status 必须为…, admin-models field validators, org field validators, gateway body validators — plus one expired-session literal that is never displayed (__atpLogout shows a different message). They fail closed as raw Chinese. Happy to cover any of them if you'd rather have full coverage.

…sh mode

ERR_MAP maps the backend's Chinese error strings to English translation keys.
Several messages returned on paths a user can actually reach were never wired
into it, so English-mode users saw raw Chinese. The clearest case was an
orphaned key: err.network was defined in both packs and its Chinese value is
exactly the literal api.js passes to mapErr on a network failure, but no
ERR_MAP entry referenced it - the translation existed and was unreachable.

Covered now (all on paths the console calls):
  err.network          网络不可用,请检查后端服务是否启动  (api.js network failure)
  err.emailNotRegistered 该邮箱未注册                       (auth/reset_password, forgot-password form)
  err.raisePending     已有待审批的加额申请,请等待管理员处理    (raise_requests/create)
  err.raiseHandled     该申请已处理                        (raise_requests approve/reject)
  err.codeSendFail     验证码发送失败,请重试                 (auth/login 502)
  err.modelExists      模型已存在(provider+model 唯一)      (admin/models create/patch)
  err.negativePrice    价格不能为负数                       (admin/models create/patch)

Six new keys were added to both packs (769 -> 775, ZH == EN); err.network
already existed and only needed wiring. Coverage of the 40 production backend
error strings goes from 18 to 24.

Verified against the true pre-fix baseline (git HEAD), replaying every real
message through the real mapErr in EN mode: exactly 7 messages change, all
from raw Chinese to English, and 0 regressions - the single merged entry that
covers two sources (err.network) is counted once. Controls: zh passthrough,
unmatched passthrough, null passthrough, and a wired key still translating.

Deliberately NOT covered, to keep this change honest rather than exhaustive:
the remaining unmapped strings are defensive validation on URLs/states the
console never generates (wallet "type must be..." / ISO-8601 params, sharing
"status must be...", admin-models field validators, org field validators,
gateway body validators), plus one literal for an expired session that is
never displayed. They fail closed as raw Chinese.
@argszero
argszero merged commit 37d5b1c into main Sep 11, 2026
1 check passed
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.

1 participant