# `error-codes.ts` ## Purpose Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes` from `@suaveplan/error`. These codes are the single source of truth for error identity across the React surface โ€” every `ReactI18nError` carries one of them as its `.code`, every spec-conformance test asserts against them, and every observability sink (OTel attributes, structured log fields, error-wire JSON) uses the fully-qualified `REACT_I18N.` string. The registry must run at module-import time so the codes are present in the global registry before any hook, component, or detector throws. The barrel imports the file as a side-effect-only entry to guarantee the registration sequence regardless of which subpath the consumer imports first. ## Features - Frozen `REACT_I18N_CODES` record with five entries โ€” added/removed only through an OpenSpec change. - `ReactI18nCode` literal-union type derived from the registry, used as the `TCode` parameter of `ReactI18nError`. - Side-effect-free constant declaration: no logger calls, no global mutation beyond what `defineCodes` performs internally on the shared registry. ## Usage: Basic Example ```ts import { REACT_I18N_CODES } from "@suaveplan/react-i18n/errors"; const code = REACT_I18N_CODES.NO_PROVIDER; // "REACT_I18N.NO_PROVIDER" ``` ## Usage: Advanced Example ```ts import { REACT_I18N_CODES, ReactI18nError, type ReactI18nCode, } from "@suaveplan/react-i18n/errors"; function assertProvider(value: unknown): asserts value { if (value === undefined || value === null) { const code: ReactI18nCode = REACT_I18N_CODES.NO_PROVIDER; throw new ReactI18nError(code, "react-i18n.no_provider", { context: { hook: "useTranslation" }, }); } } ``` ## API Reference ### `REACT_I18N_CODES` Frozen record of fully-qualified error code strings. Keys are short reason identifiers; values are the canonical `REACT_I18N.` strings. | Key | Value | | --- | --- | | `NO_PROVIDER` | `"REACT_I18N.NO_PROVIDER"` | | `NAMESPACE_LOAD_FAILED` | `"REACT_I18N.NAMESPACE_LOAD_FAILED"` | | `HYDRATION_MISMATCH` | `"REACT_I18N.HYDRATION_MISMATCH"` | | `TRANS_INVALID_CHILD` | `"REACT_I18N.TRANS_INVALID_CHILD"` | | `UNKNOWN_KEY` | `"REACT_I18N.UNKNOWN_KEY"` | ### `type ReactI18nCode` Literal union of every value in `REACT_I18N_CODES`. Used as the `TCode` parameter of `ReactI18nError` so `instanceof` narrowing on `error.code` produces a closed union. ## Implementation Notes - The codes are added/removed only through an OpenSpec change. Adding a code here without a spec amendment violates `AGENTS.md` ยง13a. Removing a code is a breaking change. - The order is the same order spec authors list the codes in โ€” keep them parallel so reviewers can scan both surfaces in one pass. - `defineCodes` returns a `Object.create(null)`-prototyped frozen record; attempts to mutate at runtime fail loudly under strict mode. - Importing this file is a side effect only insofar as `defineCodes` registers each code with the shared `@suaveplan/error` registry; importing the file twice is idempotent.