Errors need boundaries
The UI should not know every backend exception. The backend should not leak raw database errors. A useful application maps low-level failures into stable error shapes at boundaries.
Think in layers: validation errors help users correct input, network errors explain temporary failure, server errors need safe public messages and useful internal logs.
type ApiError = {
code: "VALIDATION" | "NETWORK" | "SERVER";
message: string;
fieldErrors?: Record<string, string>;
requestId?: string;
};fetch does not throw for HTTP errors
The fetch API throws for network failures, not for 400 or 500 responses. You need to check response.ok and parse the response body intentionally.
This difference matters because a 422 validation response is not the same as a dropped connection.
const response = await fetch("/api/profile", options);
if (!response.ok) {
const error = await response.json();
throw normalizeApiError(error, response.status);
}Try the idea
Please enter a valid email address.
422 VALIDATION: email format failed
User-facing and developer-facing errors are different
Users need a clear next action. Developers need enough context to debug. Mixing those two creates either vague logs or scary UI messages.
A safe error boundary can show a short message, include a request ID, and log the actual details server-side.
Error handling checklist
Use this checklist before a form, API flow, or dashboard action ships.
Production notes for JavaScript apps
When this concept moves from a tutorial into a real app, the important question is not whether the example works once. It is whether the behavior is still predictable when network latency, retries, user interaction, rendering, and logging all happen together.
Keep the boundary visible. Name the queue, state, error, or ownership rule in the code so the next developer can understand why the behavior exists without reading the whole feature from top to bottom.
Conclusion
The goal is not catching every error everywhere. The goal is making every important boundary predictable.

