React

Verified against Claude Code · 2026-07-23

Build an error boundary that lets the user actually recover

Implements a class-based error boundary — the one place hooks genuinely have no equivalent — with a real retry-and-reset UX and error reporting, instead of a static crash screen that leaves the only recovery option as a full page reload.

Claude CodeCursorChatGPTClaude4 fillable variables

The prompt

Ready to copy — highlighted parts are example details you can swap.

You are implementing a React error boundary. Error boundaries have no hook equivalent as of the current React version — componentDidCatch and static getDerivedStateFromError are only available on class components — so this must be a class component, wired into an otherwise fully functional-component codebase, with a real recovery path for the user, not just a static fallback message.

BOUNDARY SCOPE
Around each individual dashboard widget, so one broken widget does not take down the whole dashboard page.

CURRENT CODE
A grid of WidgetCard components, each rendering a different data visualization; currently a single uncaught error anywhere crashes the entire dashboard to a white screen.

RECOVERY BEHAVIOR
Show "This widget couldn't load" with a Retry button inside just that widget's space, and retrying should refetch that widget's data and remount it fresh.

ERROR REPORTING REQUIREMENT
Send to the existing Sentry client already initialized elsewhere in the app, tagged with the widget name.

IMPLEMENTATION RULES
Implement both static getDerivedStateFromError, to render the fallback UI, and componentDidCatch, to report the error, since they serve different purposes and neither one alone is sufficient — getDerivedStateFromError cannot perform side effects like network calls, and componentDidCatch cannot return a value to change what renders. Be explicit that this boundary only catches errors thrown during rendering, in lifecycle methods, and in constructors of the components below it in the tree — it does not catch errors inside event handlers, inside asynchronous code such as a promise callback or a setTimeout, or during server-side rendering; if the actual bug report describes an error inside a click handler or an async fetch callback, name that this boundary will not catch it and that a try/catch at that specific call site is the correct fix instead. Implement a real reset mechanism, not just a fallback that renders forever once tripped: expose a resetErrorBoundary function the fallback UI can call, and use React's key prop or the boundary's own resetKeys pattern so that changing a relevant piece of state — navigating to a new route, retrying a failed data fetch — actually remounts the children fresh rather than leaving them permanently in the crashed state until a full page reload. Report every caught error to the stated error-reporting destination inside componentDidCatch, including the component stack it provides, and never swallow an error silently just because a fallback UI is now showing — the fallback is for the user, the report is for you, and skipping the report loses the exact information needed to fix the actual bug later.

OUTPUT FORMAT
1. The error boundary class component, as real code, with both required lifecycle methods.
2. The fallback UI component, showing the retry/reset action wired to the boundary.
3. How the boundary is mounted around the scope named above.
4. An explicit note on what kinds of errors in this codebase this boundary will not catch, and where the corresponding try/catch needs to live instead.

Customize

Optional — swap in your own details for the highlighted parts above.

Why this works

Naming the exact scope of what an error boundary catches is not a pedantic caveat — it is the single most common reason error boundaries get blamed for "not working" in production: a team adds a boundary, an error still crashes the app, and the actual cause is that the error originated in an event handler or an async callback, which error boundaries were never designed to catch by React's own documented behavior, and without stating this explicitly the model will happily wire up a boundary that gives a false sense of coverage for exactly the errors most likely to occur in a real app with real user interactions and real network calls. Requiring both getDerivedStateFromError and componentDidCatch, and explaining why neither one alone suffices, prevents a common half-implementation where only the rendering fallback exists and errors are never actually reported anywhere, which means the team discovers a production crash from a user complaint instead of a monitoring alert, days or weeks after it started happening. The explicit reset mechanism is what separates a genuinely recoverable error boundary from the extremely common broken pattern where the boundary's own internal hasError state, once set to true, has no way back to false short of a full page reload — because a class component's state persists across re-renders of its parent by design, a fallback UI with no resetKeys or key-based remount strategy traps the user in the crashed view even after whatever caused the original error (a bad response, a stale token) has resolved. Reporting the error inside componentDidCatch rather than only inside getDerivedStateFromError is also a placement forced by React's own lifecycle contract, not an arbitrary choice: getDerivedStateFromError runs during the render phase, before commit, where side effects like a network call to an error-tracking service are explicitly unsafe and can be abandoned partway through if React discards that render pass, while componentDidCatch runs during the commit phase specifically so it is safe to perform exactly this kind of side effect — treating the two as interchangeable, or trying to report from inside getDerivedStateFromError to save a method, is the kind of shortcut that produces error reports that intermittently never arrive for reasons that have nothing to do with the reporting code itself.

What you get back

class WidgetErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, info) { reportToSentry(error, { widget: this.props.widgetName, componentStack: info.componentStack }); } render() { if (this.state.hasError) { return <WidgetErrorFallback onRetry={() => this.setState({ hasError: false })} />; } return this.props.children; } }

// Mounted per-widget, keyed so a retry remounts fresh state: <WidgetErrorBoundary widgetName="revenue-chart" key={retryCount}> <RevenueChartWidget /> </WidgetErrorBoundary>

Not caught by this boundary: an error thrown inside RevenueChartWidget's own onClick export-button handler, or inside its data-fetching promise's .catch — both need their own try/catch at the call site, since neither runs during React's render phase.

Verified against

Claude Code Sonnet 4.6 · 2026-07-23

Claude Sonnet 4.6 · 2026-08-01

Changelog

  • 2026-07-23 — Initial publish, verified against Claude Code and Claude on Sonnet 4.6.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All React prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY