Question presented to candidate: "You have an Error Boundary and a component still crashes the page. What kinds of error does it not catch?"
What a strong answer should cover:
- The unifying rule: a boundary catches errors thrown while React is on the stack rendering or committing that subtree. Anything thrown outside that window is invisible to it.
- Caught: errors during render, during
useEffectand layout effects, in constructors and other lifecycle methods. - Not caught: event handlers — React is not rendering when your click handler runs.
- Not caught: anything asynchronous —
setTimeout, promise callbacks,requestAnimationFrame. The throw happens on a later tick with no React frame below it. - Not caught: errors in server-side rendering, and errors in the boundary's own render — those go to the next boundary up.
- The practical consequences: wrap async work in try/catch and put the failure in state; a rejected promise needs
.catchor an unhandledrejection handler. - Errors thrown by a suspended promise resolving are surfaced through Suspense and do reach a boundary.
- React 19's root-level
onUncaughtErrorandonCaughtErrorgive you the reporting hook for what boundaries do and do not handle.
Clarifying questions expected:
- "Where is the throw actually happening — render, an effect, a handler, or a timer?" — that alone answers it.
- "Is the failing code a promise rejection?" — that needs a different mechanism entirely.
Code / implementation expected: Optional. A grid of four throw sites with the outcome of each is the most convincing form.