import { ErrorCode } from "@batch-cooking/shared"; import i18n from "../i18n/i18n"; /** * Centralizes lookup of the user-facing label for a given {@link ErrorCode}, * delegating the actual translation storage/lookup to i18next (see * `i18n/i18n.ts` and `locales/fr/translation.json`) — components never * hardcode error text, and adding a language is a locale file, not a * code change. * * A numeric `ErrorCode` value isn't a valid i18next key by itself (and * numeric JSON keys would be far less readable in the locale file than * names), so this reverse-maps the enum value to its member name (e.g. * `4001` → `"EMAIL_ALREADY_IN_USE"`) via TypeScript's numeric-enum reverse * mapping, then looks that name up under the `errors` namespace. */ export class ErrorMessageService { /** * Returns the localized, user-facing label for a given error code. * * @param code - Error code as returned by the API. An unrecognized value * (e.g. the client is older than the API and doesn't know a newer code) * falls back to the generic `INTERNAL_ERROR` label instead of throwing. */ public getLabel(code: ErrorCode): string { const memberName = ErrorCode[code] ?? ErrorCode[ErrorCode.INTERNAL_ERROR]; return i18n.t(`errors.${memberName}`); } } /** Single shared instance — this service is stateless, no need for one per caller. */ export const errorMessageService = new ErrorMessageService();