React Error Handling
Split failures into render errors, caught by error boundaries with a fallback, and network errors, caught with try/catch and retry. Make sure both paths end in a logged error and a usable screen.
Seedtended planted 1 min read
🌱 A rough idea, planted recently. Expect rough edges — it will grow.
Split failures into UI (render) errors, caught by error boundaries, and network errors, caught with try/catch plus retry. Then make sure both paths end in a logged error and a screen the user can still work with.
The flow
A user action can fail in two ways:
- The UI fails. A component throws, an
ErrorBoundarycatches it and shows a fallback (or cached data). The error also reaches a global handler, which logs it. - A network request fails.
try/catchcatches it and a retry mechanism backs off and tries a few more times. If it still fails, the error is logged and surfaced to the user.
Error boundaries
- They catch errors during rendering, in lifecycle methods and in constructors below them. They don’t catch errors
in event handlers, async code (
setTimeout, promises you don’t render), server rendering, or the boundary itself. Handle those with try/catch or the global handler. - The easy route is
react-error-boundary:
<ErrorBoundary FallbackComponent={Fallback} onError={log} resetKeys={[orderId]}>
<OrderPanel id={orderId} />
</ErrorBoundary>
- Place boundaries per feature or panel so one broken widget doesn’t blank the whole app, and keep one at the root as a last resort.
use(promise)and Suspense data fetching send rejections to the nearest boundary (React 19 Hooks Cheat Sheet); TanStack Query’sthrowOnErrordoes the same.
The global handler and logging
window.addEventListener("error")and"unhandledrejection"catch what boundaries miss. Forward both to your error tracker or RUM tool (Observability).try/catchonly catches a rejected promise if youawaitit.
Network errors and retry
- Retry only idempotent requests, with exponential backoff and jitter. TanStack Query retries three times by default.
- Give users distinct states: offline, 4xx (fix your input), 5xx (try again) and timeout (
AbortSignal.timeout; see React Data Fetching Patterns). - Race conditions between responses are a data-fetching bug, not an error. Cancel stale requests instead.
- #react
- #error-boundaries
- #error-handling
- #observability
- #resilience
↩ Linked from (2)
- React 19 Hooks Cheat SheetGrowing
…ntext during render (can be conditional) | Suspends on promises; rejections go to the nearest error boundary (React Error Handling) | | useEffectEvent | Pull event logic out of an effect | A stable function that always s…
What to do when a request fails is in React Error Handling; testing fetch code without mocking fetch itself is in Stop Mocking Fetch; the n+1 request problem is in Browser Fundamentals for Front-end Engineers.
↪ Links to (3)
Related by topic
- Growing
TypeScript as a Team Contract
Frontend craft - Growingcase study
A Testing Strategy Teams Actually Adopted
Frontend craft - Evergreen
Preventing XSS in React
Frontend craft - Evergreen
React Testing Strategy
Frontend craft