Web Error Handling
Purpose
Plan how the app fails: where errors are caught (route-level boundaries, async layers), what users see (actionable messages, recovery paths), and what engineers get (PII-safe reports with context). Every failure mode has a designed surface — nothing white-screens silently.
When to Use
- Alongside routing and server-state planning (errors surface through both).
- When an existing app white-screens, toasts raw messages, or reports nothing.
- Not for form-field validation UX (
web-forms) or HTTP error mapping mechanics (web-api-integration).
Inputs
- Route tree (
web-routing) — boundary placement follows it.
- Error taxonomy from
web-api-integration (network/HTTP/validation/auth unions).
- Reporting/observability expectations (tool, alerting, PII constraints).
Discovery Questions
- Which failures are recoverable in place (retry a widget) vs page-level vs app-fatal?
- What do 404, 403, 500, and offline/degraded states look like per surface (public page vs dashboard)?
- Which error-reporting service is used (or evaluated), and what must never be sent to it?
- How do auth errors route (401 → login with return path; 403 → denied view,
web-authorization)?
Responsibilities
- Place error boundaries by route segment: Next.js
error.tsx/global-error conventions or router errorElements — granular enough that a failing widget doesn't take down the shell.
- Surface async/server-state errors through the query layer's states (
web-server-state) with retry affordances where retry can help; distinguish empty from error from loading.
- Design the error pages: not-found (404), denied (403 policy per
web-authorization), server error (500), and offline/degraded behavior where relevant.
- Plan error reporting: unhandled exceptions and boundary catches shipped to the reporting service with release/route/user-context — PII and secrets scrubbed; sample noisy errors; alert on spikes.
- Write user-facing messages that say what happened and what to do next — never raw stack traces, error codes alone, or blamey copy.
- Handle global cases: unhandled promise rejections, chunk-load failures after deploys (stale clients → prompt reload), third-party script failures degrading gracefully.
Required Workflow
- Map failure modes per route segment and data dependency.
- Place boundaries and design the recovery UX per level (widget/page/app).
- Define the 404/403/500/offline pages.
- Wire reporting with scrubbing rules and alert thresholds.
- Record the plan; verify the high-traffic paths' error states in tests (
web-component-testing, playwright-e2e).
Decision Rules
- Catch at the lowest level that can still render something useful; re-throw what it can't handle.
- Retry affordances only where retry can plausibly succeed (network blips — yes; 403 — no).
- 404 vs 403 disclosure policy is decided once with
web-authorization, not per page.
- Chunk-load errors after a deploy are a reload prompt, not a crash report storm.
Rules
- No raw exception text, stack traces, or internal identifiers in user-visible UI.
- No PII, credentials, or tokens in error reports or logs.
- Every boundary's fallback is a designed state (message + action), not an empty div.
Anti-Patterns
- One app-root boundary as the only net — any error blanks the whole app.
catch {} swallowing failures so the UI lies about success.
- Toasting
err.message from the server directly to users.
- Error tracking that nobody triages, drowning in unsampled noise.
Validation Checklist
Definition of Done
A recorded error-handling plan — boundary map, recovery UX per level, error pages, PII-safe reporting, and global-case handling — under which every known failure mode renders a designed state and reaches engineers with context.
Related Skills
web-routing, web-server-state, web-api-integration, web-forms, web-authorization, web-component-testing, playwright-e2e, ../../security-review.
Related Knowledge
../../../knowledge/ (observability stack, support workflows).
Related References
../../../references/web/ (error-state copy patterns — when populated).
Context Loading Guidance
- Requires: route tree, error taxonomy, reporting expectations.
- Does not require: styling detail, unrelated features.
- May load:
web-server-state for query-error states; web-authorization for 403 policy.
- Stop when: the boundary map and reporting plan are recorded.
Token Efficiency Guidance
Work from a failure-mode table (mode → boundary level → user sees → reported?). Copywriting detail goes to references.
1---2name: web-error-handling3description: Use to plan web error handling — route-level error boundaries (Next.js error.tsx / router errorElement), async and server-state error surfacing, 404/500 pages, PII-safe error reporting, actionable user-facing messages, and retry paths. Users never see raw stack traces.4---56# Web Error Handling78## Purpose910Plan how the app fails: where errors are caught (route-level boundaries, async layers), what users see (actionable messages, recovery paths), and what engineers get (PII-safe reports with context). Every failure mode has a designed surface — nothing white-screens silently.1112## When to Use1314- Alongside routing and server-state planning (errors surface through both).15- When an existing app white-screens, toasts raw messages, or reports nothing.16- **Not** for form-field validation UX (`web-forms`) or HTTP error mapping mechanics (`web-api-integration`).1718## Inputs1920- Route tree (`web-routing`) — boundary placement follows it.21- Error taxonomy from `web-api-integration` (network/HTTP/validation/auth unions).22- Reporting/observability expectations (tool, alerting, PII constraints).2324## Discovery Questions2526- Which failures are recoverable in place (retry a widget) vs page-level vs app-fatal?27- What do 404, 403, 500, and offline/degraded states look like per surface (public page vs dashboard)?28- Which error-reporting service is used (or evaluated), and what must never be sent to it?29- How do auth errors route (401 → login with return path; 403 → denied view, `web-authorization`)?3031## Responsibilities3233- Place **error boundaries by route segment**: Next.js `error.tsx`/`global-error` conventions or router `errorElement`s — granular enough that a failing widget doesn't take down the shell.34- Surface **async/server-state errors** through the query layer's states (`web-server-state`) with retry affordances where retry can help; distinguish empty from error from loading.35- Design the **error pages**: not-found (404), denied (403 policy per `web-authorization`), server error (500), and offline/degraded behavior where relevant.36- Plan **error reporting**: unhandled exceptions and boundary catches shipped to the reporting service with release/route/user-context — **PII and secrets scrubbed**; sample noisy errors; alert on spikes.37- Write **user-facing messages** that say what happened and what to do next — never raw stack traces, error codes alone, or blamey copy.38- Handle **global cases**: unhandled promise rejections, chunk-load failures after deploys (stale clients → prompt reload), third-party script failures degrading gracefully.3940## Required Workflow41421. Map failure modes per route segment and data dependency.432. Place boundaries and design the recovery UX per level (widget/page/app).443. Define the 404/403/500/offline pages.454. Wire reporting with scrubbing rules and alert thresholds.465. Record the plan; verify the high-traffic paths' error states in tests (`web-component-testing`, `playwright-e2e`).4748## Decision Rules4950- Catch at the lowest level that can still render something useful; re-throw what it can't handle.51- Retry affordances only where retry can plausibly succeed (network blips — yes; 403 — no).52- 404 vs 403 disclosure policy is decided once with `web-authorization`, not per page.53- Chunk-load errors after a deploy are a reload prompt, not a crash report storm.5455## Rules5657- No raw exception text, stack traces, or internal identifiers in user-visible UI.58- No PII, credentials, or tokens in error reports or logs.59- Every boundary's fallback is a designed state (message + action), not an empty div.6061## Anti-Patterns6263- One app-root boundary as the only net — any error blanks the whole app.64- `catch {}` swallowing failures so the UI lies about success.65- Toasting `err.message` from the server directly to users.66- Error tracking that nobody triages, drowning in unsampled noise.6768## Validation Checklist6970- [ ] Boundaries placed per route segment with designed fallbacks.71- [ ] Async/server-state error surfacing defined with retry policy.72- [ ] 404/403/500/offline pages designed.73- [ ] Reporting wired with PII scrubbing and alerting.74- [ ] Global cases handled (rejections, chunk-load, third-party).75- [ ] Error states of critical paths covered in tests.7677## Definition of Done7879A recorded error-handling plan — boundary map, recovery UX per level, error pages, PII-safe reporting, and global-case handling — under which every known failure mode renders a designed state and reaches engineers with context.8081## Related Skills8283`web-routing`, `web-server-state`, `web-api-integration`, `web-forms`, `web-authorization`, `web-component-testing`, `playwright-e2e`, `../../security-review`.8485## Related Knowledge8687`../../../knowledge/` (observability stack, support workflows).8889## Related References9091`../../../references/web/` (error-state copy patterns — when populated).9293## Context Loading Guidance9495- **Requires:** route tree, error taxonomy, reporting expectations.96- **Does not require:** styling detail, unrelated features.97- **May load:** `web-server-state` for query-error states; `web-authorization` for 403 policy.98- **Stop when:** the boundary map and reporting plan are recorded.99100## Token Efficiency Guidance101102Work from a failure-mode table (mode → boundary level → user sees → reported?). Copywriting detail goes to references.