Lesson 22 / 25
Error Boundaries
Contain rendering errors.
Fallback UI for a subtree
If a component throws during rendering, React unmounts the whole tree unless an error boundary catches it. An error boundary is a class component with static getDerivedStateFromError (to show fallback UI) and optionally componentDidCatch (to log the error). Place boundaries around independent areas (a widget, a page section) so one failure does not blank the whole app. Error boundaries do not catch errors in event handlers or async code; handle those with try/catch and state.
One failing widget, one working, run
I ran this with React 19.3 and react-dom 19.3 on Node.js 22, compiling JSX with esbuild 0.28. Browser-style examples use jsdom 29 as a fake DOM (imported from a small setup-dom.mjs file) and act() to apply updates. Two prices are wrapped in separate error boundaries. The one with an amount renders "Rs 499"; the one missing its amount throws, the boundary logs "price missing" and shows "Something went wrong." while the rest of the page keeps working.
import "./setup-dom.mjs"; // test setup: jsdom provides a browser-like DOM in Node
import { Component, act } from "react";
import { createRoot } from "react-dom/client";
class ErrorBoundary extends Component {
state = { error: null };
static getDerivedStateFromError(error) { return { error }; }
componentDidCatch(error) { console.log("logged:", error.message); }
render() { return this.state.error ? <p>Something went wrong.</p> : this.props.children; }
}
function Price({ amount }) {
if (amount == null) throw new Error("price missing");
return <p>Rs {amount}</p>;
}
const origError = console.error; console.error = () => {}; // hide React's dev error report
const root = createRoot(document.getElementById("root"));
await act(() => root.render(<><ErrorBoundary><Price amount={499} /></ErrorBoundary><ErrorBoundary><Price /></ErrorBoundary></>));
console.error = origError;
console.log([...document.querySelectorAll("p")].map(p => p.textContent));
Output:
logged: price missing [ 'Rs 499', 'Something went wrong.' ]
Report caught errors
Send errors from componentDidCatch to your error-tracking service with context, not just to the console.
Quick check: Which errors do error boundaries catch?
- Syntax errors in other files
- Errors in event handlers
- Network errors in fetch calls by default
- Errors thrown while rendering components below them
Answer
Errors thrown while rendering components below them — Use try/catch for handlers and async code.