React error boundaries catch errors thrown while rendering descendant components and in certain lifecycle methods; global handlers catch different uncaught errors, such as unhandled browser-level exceptions and rejected promises. Neither mechanism catches every error, so robust React apps use boundaries for UI recovery and global listeners for visibility into errors that escape them.
What React error boundaries catch
An error boundary is a React component that catches errors in its child component tree during rendering, in constructors, and in class-component lifecycle methods. When a descendant fails, the boundary can record the error and display fallback UI instead of letting the affected part of the interface render normally.
For example, if a product card throws while calculating its displayed price during render, a boundary around the card list can replace the failed area with a message while leaving the rest of the page available. A boundary higher in the tree can instead replace a larger portion of the application.
In current React APIs, boundaries are implemented with class components using methods such as getDerivedStateFromError and componentDidCatch. React does not provide a built-in function-component boundary hook. Libraries can offer boundary components and additional conveniences, but the underlying catch scope remains the descendant React tree.
What global error handlers catch
“Global error handler” can refer to several mechanisms rather than one universal catcher. In browsers, window.onerror can observe many uncaught synchronous JavaScript exceptions, while the unhandledrejection event reports promise rejections that have not been handled. These listeners are useful for logging errors that do not reach a React boundary.
For example, a timer callback that throws after a component has rendered is not a render-time descendant error for a boundary to catch. If that exception is uncaught, a browser-level handler may observe it. Likewise, a fetch promise that rejects without a .catch() handler may trigger unhandledrejection; a boundary does not automatically catch that rejection.
Global listeners are not a guarantee that every fault will be reported. Browser behavior and details such as cross-origin scripts can affect what information an error event exposes. A handled exception or rejection generally will not count as an unhandled global error. Also, a global listener can report a problem but cannot reliably decide which React subtree should be replaced with fallback UI.
How the catch scopes differ
The key distinction is where and when the error occurs. A boundary is integrated with React’s rendering process and can change the UI for a failed subtree. Global handlers sit outside that recovery mechanism and observe certain uncaught JavaScript errors at the page level.
- Render failure: A component throws while React renders it. A surrounding boundary can catch the error and show fallback content.
- Event handler failure: A click handler throws. Error boundaries do not catch ordinary event-handler errors. Handle them in the event code, or let an uncaught exception reach a global handler.
- Asynchronous callback failure: An error in a timer or other callback after rendering is outside the boundary’s normal catch scope. Catch it locally or use global reporting for uncaught exceptions.
- Rejected promise: A boundary does not catch a rejection simply because it originated in a component. Handle the rejection, or a browser’s unhandled-rejection event may report it if it remains unhandled.
- Server rendering: Browser globals such as
window.onerrordo not run on the server. Server rendering has its own error handling and reporting path.
React has a specific integration for errors that are deliberately re-thrown during rendering. For example, an event handler can save an error in state, then render code can throw that error so a boundary handles the resulting UI failure. This is an explicit handoff, not automatic catching of the original event or promise.
What neither mechanism catches automatically
Common misconceptions come from assuming that a boundary is equivalent to JavaScript’s try...catch. It is not. A boundary does not catch errors in itself, ordinary event handlers, asynchronous callbacks, or server-side rendering. It also does not automatically observe every failed network request: application code must handle the request’s rejected promise or turn its failure into a render-time error that a boundary can catch.
Global handlers have limits too. They are primarily for uncaught errors and unhandled rejections; they do not provide component-level fallback behavior. If code catches an error and silently ignores it, a global unhandled-error listener may never see it. Conversely, logging an error globally does not make the affected component safe to render again.
A boundary also cannot promise that recovery is possible. If its fallback itself fails, the next enclosing boundary may be needed. If no suitable boundary exists, React may be unable to preserve the affected UI. Place boundaries at meaningful recovery points, and keep fallback content simple.
How to use both in an application
Use boundaries to contain failures and give users a useful interface. Use global listeners as a last-resort reporting layer for errors that escape local handling. Add local handling where the application can make a better decision, such as showing a failed-save message or retry control for a rejected request.
- Choose boundary locations around independent areas that can fail separately, such as a route, dashboard panel, or optional widget.
- Provide a clear fallback that explains the affected area is unavailable and, where appropriate, offers a retry or navigation option.
- Handle expected failures locally. For example, check a promise rejection from a data request and update component state to display a loading, success, or error state.
- Register browser-level error and unhandled-rejection reporting where appropriate, and send useful context to the application’s logging system.
- Avoid duplicate or misleading reports. If an error is caught and deliberately handled, record it at the point where that handling decision is made rather than assuming a global listener will see it.
Keep sensitive data out of logs, and distinguish expected operational failures from programming errors. A failed request can be a normal state the interface should explain, while an uncaught render exception usually indicates a defect or unexpected condition that merits investigation.
Choosing the right handler
Choose an error boundary when the immediate need is to keep a portion of the React interface from collapsing and show fallback UI. Choose a global handler when the need is to observe uncaught errors or unhandled rejections across the browser page. They solve different problems, so most substantial applications benefit from both, alongside ordinary local error handling.
For a concrete choice, ask two questions: can the code handle this failure where it occurs, and should the user see a replacement for a particular UI region? Handle expected failures locally. Use a boundary for render-tree failures. Use global listeners to capture unexpected failures that remain uncaught, not as a substitute for either of those approaches.
Frequently Asked Questions
Do React error boundaries catch errors in event handlers?
No. Handle exceptions in the event handler itself, or allow an uncaught exception to reach a global browser handler. A boundary can respond if the error is explicitly passed into state and thrown during a later render.
Can an error boundary catch a rejected promise?
Not merely because the promise was created by a component. Handle the rejection with promise or async control flow. If it remains unhandled, the browser may emit an unhandledrejection event.
Does window.onerror replace React error boundaries?
No. It can report many uncaught synchronous browser errors, but it does not provide React subtree fallback UI and does not replace handling for promise rejections or expected application failures.
Do error boundaries catch errors in their own fallback UI?
No. A boundary cannot catch errors thrown by itself. An enclosing boundary may catch a failure in a nested boundary or its fallback.
Should I use both boundaries and global error handlers?
Usually, yes. Boundaries support localized UI recovery; global handlers can report certain uncaught errors. Add local handling for expected failures such as a request that the interface can explain or retry.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Delete Picture Kik? How to Remove Photos
- What Happens to X Replies, DMs, and Followers After Deletion?
- Data Breaches That Shook the World
- Disable Google Assistant: Turn It Off on Android & Home
- Resin vs FDM Printers for Miniatures: Detail, Durability, Cost
- Are Networked Implants Safe? What If One Fails?