refactor(api): code-review fixes (R7 S1)

- localizeDetail: don't leak FastAPI's snake_case `loc` field names into a
  translated 422 toast; return a clean, fully localized validation message
  (drops the loc filter/pop parsing entirely)
- me(): drop the dead `r &&` guard now that req<T> types r non-nullable
This commit is contained in:
2026-07-26 22:17:04 +02:00
parent 16585d868d
commit d0aa1cf9a7
3 changed files with 7 additions and 12 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"title": "Couldn't complete that",
"generic": "The server couldn't carry out that action. Please try again.",
"validation": "Invalid value for “{{field}}”. Please check it and try again.",
"validation": "Some of the values you entered weren't valid. Please check them and try again.",
"server": "Server error",
"ok": "OK",
"offline": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"title": "Nem sikerült",
"generic": "A szerver nem tudta végrehajtani a műveletet. Próbáld újra.",
"validation": "Érvénytelen érték: „{{field}}”. Ellenőrizd, majd próbáld újra.",
"validation": "Néhány megadott érték érvénytelen volt. Ellenőrizd, majd próbáld újra.",
"server": "Szerverhiba",
"ok": "OK",
"offline": {
+5 -10
View File
@@ -228,15 +228,10 @@ class HttpError extends Error {
function localizeDetail(d: unknown): string {
const t = i18n.t.bind(i18n);
// FastAPI request-validation errors: `detail` is an ARRAY of { loc, msg, type }. The UI sends
// well-formed requests, so this only fires on genuinely malformed input — surface the offending
// field name (localized) rather than FastAPI's raw English `msg`, which reads wrong in a HU UI.
if (Array.isArray(d)) {
const loc = (d[0] as { loc?: unknown } | undefined)?.loc;
const field = Array.isArray(loc)
? loc.filter((s): s is string => typeof s === "string" && s !== "body").pop()
: undefined;
return field ? t("errors.validation", { field }) : t("errors.generic");
}
// well-formed requests, so this only fires on genuinely malformed input. The per-field `msg` and
// `loc` field names are English, snake_case internal tokens — surface a clean, fully localized
// "check your input" message rather than leaking them into a translated sentence.
if (Array.isArray(d)) return t("errors.validation");
const o = d as { code?: string; reason?: string; limit?: number } | null | undefined;
if (o?.code === "quota") {
if (o.reason === "max_bytes") {
@@ -1117,7 +1112,7 @@ export const api = {
me: async (): Promise<Me | null> => {
// Always 200: `{ authenticated: false }` when logged out, else the full Me + `authenticated`.
const r = await req<{ authenticated: boolean } & Partial<Me>>("/api/me");
return r && r.authenticated ? (r as Me) : null;
return r.authenticated ? (r as Me) : null;
},
accounts: (): Promise<Account[]> => req("/api/me/accounts"),
deleteAccount: (): Promise<{ deleted: boolean }> => req("/api/me/account", { method: "DELETE" }),