3.5 KiB
useValidationMessageBridge
(no submodules)
Purpose
Centralised resolver factory turning a SuaveplanError (or any thrown value) into a locale-resolved user-facing message. Mirrors the resolution rules of useErrorMessage from @suaveplan/react-i18n but returns a function — so a single hook call gives you a resolver you can apply to many errors per render: a list of validation errors on a form, a batch of toasts, a fan-out of notifications, or a status panel summarising recent failures. Every UI surface in react-ui (Toast, Alert, Dialog, ConfirmDeleteDialog) that needs to render an error should resolve through this bridge so the catalog-lookup behaviour stays consistent across the chassis.
Features
- One hook call yields a resolver suitable for many errors.
- Walks the
causechain to surface the deepestSuaveplanError. - Catalog lookup (
errors:<code>) on hit; falls back toerror.messageon miss. - Coerces non-
Errorinputs (strings, undefined) without throwing. - Stable function reference across renders (memoized by
useCallback).
Usage: Basic Example
import { useValidationMessageBridge } from "@suaveplan/react-ui";
function FormErrors({ errors }: { errors: SuaveplanError[] }) {
const resolve = useValidationMessageBridge();
return (
<ul>
{errors.map((e, i) => <li key={i}>{resolve(e)}</li>)}
</ul>
);
}
Usage: Advanced Example
Render a batch of validation errors inside an Alert with the bridge resolver:
function ValidationSummary({ errors }: { errors: unknown[] }) {
const resolve = useValidationMessageBridge();
return (
<Alert variant="destructive">
<AlertTitle>Please fix the following</AlertTitle>
<AlertDescription>
<ul>
{errors.map((err, i) => (
<li key={i}>{resolve(err)}</li>
))}
</ul>
</AlertDescription>
</Alert>
);
}
A try/catch handler that surfaces a toast with the resolved message:
function useSubmit() {
const resolve = useValidationMessageBridge();
const { toast } = useToast();
return useCallback(async (input: FormValues) => {
try {
await save(input);
} catch (err) {
toast({ variant: "destructive", description: resolve(err) });
}
}, [resolve, toast]);
}
API Reference
useValidationMessageBridge(): ValidationMessageResolver
Returns (error: unknown) => string. Resolution order:
null/undefined→"".- Walk cause chain → first
SuaveplanErrorwins. Look uperrors:<code>; on hit return the translation, on miss return the surfaced error's.message. - Plain
Error→error.message. string→ itself.- Anything else →
"".
Implementation Notes
- The hook reads the i18n instance via
useI18n()and memoizes the resolver withuseCallback([i18n])so the function reference is stable as long as the i18n instance is. Languages-changed events bump i18n's snapshot counter; the bridge's resolver re-binds when that propagates so subsequent calls see the new locale's catalog. - Cause-chain walking is bounded at depth 10 to prevent runaway loops on accidentally-cyclic error structures.
- The bridge does NOT perform any side effects (no logging, no telemetry). For metric emission on errors, wrap the call site or compose with
@suaveplan/logger.