Security News
vlt Debuts New JavaScript Package Manager and Serverless Registry at NodeConf EU
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
react-error-boundary
Advanced tools
The react-error-boundary package provides a simple and reusable wrapper component that catches JavaScript errors in their child component tree, logs those errors, and displays a fallback UI instead of the component tree that crashed. It is designed to handle errors that occur during rendering, in lifecycle methods, and in constructors of the whole tree below them.
Error Boundary Wrapper
This feature allows you to wrap your components with an ErrorBoundary component. You can specify a FallbackComponent to be displayed when an error is caught, and an onError handler to log or report errors.
{"<ErrorBoundary FallbackComponent={MyFallbackComponent} onError={myErrorHandler}>
<MyWidget />
</ErrorBoundary>"}
useErrorHandler Hook
The useErrorHandler hook can be used within functional components to handle errors. When an error is caught, it can be passed to the handleError function provided by the hook, which will then trigger the nearest error boundary.
{"const handleError = useErrorHandler();
try {
// Some operation that might fail
} catch (error) {
handleError(error);
}"}
This package provides an overlay for displaying runtime errors in React applications. It is similar to react-error-boundary in that it helps developers handle errors, but it focuses on providing a development-time overlay that displays errors rather than a production-ready error boundary component.
React-error-guard is a package that provides error boundary functionality with a focus on simplicity and minimalism. It is similar to react-error-boundary but may have fewer features and a simpler API, which could be beneficial for smaller projects or for developers who prefer a more straightforward approach.
Simple reusable React error boundary component
React v16 introduced the concept of “error boundaries”.
This component provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled.
Reading this blog post will help you understand what react-error-boundary does for you: Use react-error-boundary to handle errors in React – How to simplify your React apps by handling React errors effectively with react-error-boundary
This module is distributed via npm which is bundled with node and
should be installed as one of your project's dependencies
:
npm install --save react-error-boundary
The simplest way to use <ErrorBoundary>
is to wrap it around any component
that may throw an error. This will handle errors thrown by that component and
its descendants too.
import {ErrorBoundary} from 'react-error-boundary'
function ErrorFallback({error, componentStack, resetErrorBoundary}) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<pre>{componentStack}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
const ui = (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// reset the state of your app so the error doesn't happen again
}}
>
<ComponentThatMayError />
</ErrorBoundary>
)
You can react to errors (e.g. for logging) by providing an onError
callback:
import {ErrorBoundary} from 'react-error-boundary'
const myErrorHandler = (error: Error, componentStack: string) => {
// Do something with the error
// E.g. log to an error logging client here
}
const ui = (
<ErrorBoundary FallbackComponent={ErrorFallback} onError={myErrorHandler}>
<ComponentThatMayError />
</ErrorBoundary>,
)
You can also use it as a higher-order component:
import {withErrorBoundary} from 'react-error-boundary'
const ComponentWithErrorBoundary = withErrorBoundary(ComponentThatMayError, {
FallbackComponent: ErrorBoundaryFallbackComponent,
onError(error, componentStack) {
// Do something with the error
// E.g. log to an error logging client here
},
})
const ui = <ComponentWithErrorBoundary />
In the event of an error if you want to recover from that error and allow the user to "try again" or continue with their work, you'll need a way to reset the ErrorBoundary's internal state. You can do this various ways, but here's the most idiomatic approach:
function ErrorFallback({error, componentStack, resetErrorBoundary}) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<pre>{componentStack}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
function Bomb() {
throw new Error('💥 CABOOM 💥')
}
function App() {
const [explode, setExplode] = React.useState(false)
return (
<div>
<button onClick={() => setExplode(e => !e)}>toggle explode</button>
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => setExplode(false)}
resetKeys={[explode]}
>
{explode ? <Bomb /> : null}
</ErrorBoundary>
</div>
)
}
So, with this setup, you've got a button which when clicked will trigger an
error. Clicking the button again will trigger a re-render which recovers from
the error (we no longer render the <Bomb />
). We also pass the resetKeys
prop which is an array of elements for the ErrorBoundary
to check each render
(if there's currently an error state). If any of those elements change between
renders, then the ErrorBoundary
will reset the state which will re-render the
children.
We have the onReset
prop so that if the user clicks the "Try again" button we
have an opportunity to re-initialize our state into a good place before
attempting to re-render the children.
This combination allows us both the opportunity to give the user something specific to do to recover from the error, and recover from the error by interacting with other areas of the app that might fix things for us. It's hard to describe here, but hopefully it makes sense when you apply it to your specific scenario.
ErrorBoundary
propschildren
This is what you want rendered when everything's working fine. If there's an
error that React can handle within the children of the ErrorBoundary
, the
ErrorBoundary
will catch that and allow you to handle it gracefully.
FallbackComponent
This is a component you want rendered in the event of an error. As props it will
be passed the error
, componentStack
, and resetErrorBoundary
(which will
reset the error boundary's state when called, useful for a "try again" button
when used in combination with the onReset
prop).
This is required if no fallback
or fallbackRender
prop is provided.
fallbackRender
This is a render-prop based API that allows you to inline your error fallback UI
into the component that's using the ErrorBoundary
. This is useful if you need
access to something that's in the scope of the component you're using.
It will be called with an object that has error
, componentStack
, and
resetErrorBoundary
:
const ui = (
<ErrorBoundary
fallbackRender={({error, resetErrorBoundary}) => (
<div role="alert">
<div>Oh no</div>
<pre>{error.message}</pre>
<button
onClick={() => {
// this next line is why the fallbackRender is useful
resetComponentState()
// though you could accomplish this with a combination
// of the FallbackCallback and onReset props as well.
resetErrorBoundary()
}}
>
Try again
</button>
</div>
)}
>
<ComponentThatMayError />
</ErrorBoundary>
)
I know what you're thinking: I thought we ditched render props when hooks came around. Unfortunately, the current React Error Boundary API only supports class components at the moment, so render props are the best solution we have to this problem.
This is required if no FallbackComponent
or fallback
prop is provided.
fallback
In the spirit of consistency with the React.Suspense
component, we also
support a simple fallback
prop which you can use for a generic fallback. This
will not be passed any props so you can't show the user anything actually useful
though, so it's not really recommended.
const ui = (
<ErrorBoundary fallback={<div>Oh no</div>}>
<ComponentThatMayError />
</ErrorBoundary>
)
onError
This will be called when there's been an error that the ErrorBoundary
has
handled. It will be called with two arguments: error
, componentStack
.
onReset
This will be called immediately before the ErrorBoundary
resets it's internal
state (which will result in rendering the children
again). You should use this
to ensure that re-rendering the children will not result in a repeat of the same
error happening again.
onReset
will be called with whatever resetErrorBoundary
is called with.
Important: onReset
will not be called when reset happens from a change
in resetKeys
. Use onResetKeysChange
for that.
resetKeys
Sometimes an error happens as a result of local state to the component that's
rendering the error. If this is the case, then you can pass resetKeys
which is
an array of values. If the ErrorBoundary
is in an error state, then it will
check these values each render and if they change from one render to the next,
then it will reset automatically (triggering a re-render of the children
).
See the recovery examples above.
onResetKeysChange
This is called when the resetKeys
are changed (triggering a reset of the
ErrorBoundary
). It's called with the prevResetKeys
and the resetKeys
.
useErrorHandler(error?: Error)
React's error boundaries feature is limited in that the boundaries can only handle errors thrown during React's lifecycles. To quote the React docs on Error Boundaries:
Error boundaries do not catch errors for:
- Event handlers (learn more)
- Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
- Server side rendering
- Errors thrown in the error boundary itself (rather than its children)
This means you have to handle those errors yourself, but you probably would like
to reuse the error boundaries you worked hard on creating for those kinds of
errors as well. This is what useErrorHandler
is for.
There are two ways to use useErrorHandler
:
const handleError = useErrorHandler()
: call handleError(theError)
useErrorHandler(error)
: useful if you are managing the error state yourself
or get it from another hook.Here's an example:
function Greeting() {
const [greeting, setGreeting] = React.useState(null)
const handleError = useErrorHandler()
function handleSubmit(event) {
event.preventDefault()
const name = event.target.elements.name.value
fetchGreeting(name).then(
newGreeting => setGreeting(newGreeting),
handleError,
)
}
return greeting ? (
<div>{greeting}</div>
) : (
<form onSubmit={handleSubmit}>
<label>Name</label>
<input id="name" />
<button type="submit" onClick={handleClick}>
get a greeting
</button>
</form>
)
}
Note, in case it's not clear what's happening here, you could also write
handleClick
like this:
function handleSubmit(event) {
event.preventDefault()
const name = event.target.elements.name.value
fetchGreeting(name).then(
newGreeting => setGreeting(newGreeting),
error => handleError(error),
)
}
Alternatively, let's say you're using a hook that gives you the error:
function Greeting() {
const [name, setName] = React.useState('')
const {greeting, error} = useGreeting(name)
useErrorHandler(error)
function handleSubmit(event) {
event.preventDefault()
const name = event.target.elements.name.value
setName(name)
}
return greeting ? (
<div>{greeting}</div>
) : (
<form onSubmit={handleSubmit}>
<label>Name</label>
<input id="name" />
<button type="submit" onClick={handleClick}>
get a greeting
</button>
</form>
)
}
In this case, if the error
is ever set to a truthy value, then it will be
propagated to the nearest error boundary.
In either case, you could handle those errors like this:
const ui = (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Greeting />
</ErrorBoundary>
)
And now that'll handle your runtime errors as well as the async errors in the
fetchGreeting
or useGreeting
code.
Looking to contribute? Look for the Good First Issue label.
Please file an issue for bugs, missing documentation, or unexpected behavior.
Please file an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.
MIT
FAQs
Simple reusable React error boundary component
The npm package react-error-boundary receives a total of 2,673,702 weekly downloads. As such, react-error-boundary popularity was classified as popular.
We found that react-error-boundary demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
Security News
Research
The Socket Research Team uncovered a malicious Python package typosquatting the popular 'fabric' SSH library, silently exfiltrating AWS credentials from unsuspecting developers.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.