fix(i18n): localize API error messages by code (no more raw English)

Error toasts surfaced the raw English backend message. Added an errors namespace (fa/ar/en) keyed by error code + a useApiError() resolver that maps ApiClientError.code to the localized message (fallback to a localized generic). Wired into menu, tables, demo banner, and subscription checkout; hardened getErrorMessage so it never returns the raw backend message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-02 00:04:48 +03:30
parent 7519f474f3
commit 75d5bbc84a
9 changed files with 123 additions and 19 deletions
+4 -1
View File
@@ -46,7 +46,10 @@ export const notify = {
};
export function getErrorMessage(err: unknown, fallback: string): string {
if (err instanceof ApiClientError) return err.message;
// ApiClientError.message is the raw (usually English) backend message; prefer
// the caller's localized fallback. For code-specific localized text, use the
// useApiError() hook instead of this helper.
if (err instanceof ApiClientError) return fallback;
if (err instanceof Error && err.message) return err.message;
return fallback;
}
+21
View File
@@ -0,0 +1,21 @@
import { useTranslations } from "next-intl";
import { ApiClientError } from "@/lib/api/client";
/**
* Returns a resolver that turns any caught error into a localized, user-facing
* message using the "errors" namespace. Known ApiClientError codes map to their
* translated message; otherwise the provided fallback is used, then a generic
* localized message. Never surfaces the raw (English) backend message.
*
* const apiError = useApiError();
* onError: (err) => notify.error(apiError(err))
*/
export function useApiError() {
const t = useTranslations("errors");
return (err: unknown, fallback?: string): string => {
if (err instanceof ApiClientError && err.code && t.has(err.code)) {
return t(err.code);
}
return fallback ?? t("generic");
};
}