Repository navigation
fix(ui): resolve backend error messages by longest match instead of first match - #164
Merged
Merged
Conversation
…irst match
ERR_MAP in ui/js/i18n.js maps the backend's Chinese error strings to English
translation keys, and mapErr() returned on the FIRST entry whose literal was a
substring of the message. Because the table mixes generic and specific literals,
two specific entries were permanently unreachable:
"不存在" -> err.notFound shadowed "验证码不存在或已过期" -> err.codeExpired
"验证码错误" -> err.badCode shadowed "验证码错误次数过多" -> err.codeLocked
so in English mode the login/verification flows showed the wrong text
("Resource not found" / "Incorrect verification code") even though the two
correct translations already existed. Only those two entries were affected;
an all-pairs sweep of the 22 entries found exactly two shadowing pairs.
Fix: select the LONGEST matching literal, which makes resolution independent of
table order, and reorder the table longest-first so the most specific entries
read first and newly inserted entries cannot reintroduce the problem.
Verified by replaying real backend messages through the real mapErr in EN mode:
"验证码不存在或已过期,请重新获取" -> "Code invalid or expired, please request a new one"
"验证码错误次数过多,请重新获取" -> "Too many wrong attempts, please request a new code"
200 random shuffles of the table x 19 messages produce identical results
(0 mismatches), while the previous first-match algorithm mismatches under the
same shuffling (288) - confirming order no longer determines the outcome.
Mapping set unchanged: 22 entries in, 22 out, none lost or duplicated.
8 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ERR_MAPinui/js/i18n.jsmaps the backend's Chinese error strings to English translation keys, andmapErr()returned on the first entry whose literal was a substring of the message. The table mixes generic and specific literals, so two specific entries were permanently unreachable:验证码不存在或已过期err.codeExpired不存在→err.notFound验证码错误次数过多err.codeLocked验证码错误→err.badCodeIn English mode this made the verification-code flows show the wrong text, even though both correct translations already existed in the pack:
验证码不存在或已过期,请重新获取→ "Resource not found" (should be "Code invalid or expired, please request a new one")验证码错误次数过多,请重新获取→ "Incorrect verification code" (should be "Too many wrong attempts, please request a new code")The backend messages live at
src/routes/mod.rs:284,:291(reset-password) and:394,:401(email verification);mapErris applied to every user-visible error message inapp.js, so the wrong text is what users actually see.An all-pairs sweep of all 22 entries found exactly two shadowing pairs, both with different keys — only these two mappings were affected. No other message changes.
Related Issue
Changes
ui/js/i18n.js—mapErr()now selects the longest matching literal instead of the first one, which makes resolution independent of table order. The table is additionally reordered longest-first so the most specific entries read first and newly inserted entries cannot reintroduce the same problem. The mapping set is unchanged (22 entries in, 22 out; none lost, added, or duplicated).ui/index.html— cache-bust?v=20260911-8→-9(5 references).No new keys and no new vocabulary: both
err.codeExpiredanderr.codeLockedalready existed.Tests
cargo test— 148 passed; 0 failedcargo fmt --check— cleancargo clippy --all-targets -- -D warnings— cleannode --checkon all fourui/js/*.js— cleanVerification of the actual behaviour (the repo has no JS test harness — its convention is Rust
#[cfg(test)], and CI runs fmt/clippy/test only, so I did not add a new JS test runner as that would exceed the scope of this fix):mapErrin EN mode — both now resolve to the specific entry, and previously-correct mappings (点数余额不足,该邮箱已注册, the generic不存在fallback) are unchanged.nullinput passthrough ✅.Checklist
fix/<description>)fix(ui): …)Follow-up (not in this PR)
A separate, larger gap is measurable but deliberately left out to keep this change reviewable: of the 40 distinct Chinese error strings the backend can return, 18 are covered by
ERR_MAPand 22 are not, and the uncovered ones render raw Chinese in English mode (e.g.该邮箱未注册on the login path,src/routes/mod.rs:388). Happy to follow up with that coverage expansion if wanted.