react-error-boundary 3.1.4 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -392
- package/dist/react-error-boundary.d.ts +65 -0
- package/dist/react-error-boundary.d.ts.map +1 -0
- package/dist/react-error-boundary.js +167 -0
- package/dist/react-error-boundary.js.map +1 -0
- package/dist/react-error-boundary.module.js +147 -0
- package/dist/react-error-boundary.module.js.map +1 -0
- package/package.json +28 -33
- package/CHANGELOG.md +0 -5
- package/dist/index.d.ts +0 -58
- package/dist/react-error-boundary.cjs.d.ts +0 -1
- package/dist/react-error-boundary.cjs.js +0 -171
- package/dist/react-error-boundary.esm.d.ts +0 -1
- package/dist/react-error-boundary.esm.js +0 -142
- package/dist/react-error-boundary.umd.d.ts +0 -1
- package/dist/react-error-boundary.umd.js +0 -187
- package/dist/react-error-boundary.umd.js.map +0 -1
- package/dist/react-error-boundary.umd.min.d.ts +0 -1
- package/dist/react-error-boundary.umd.min.js +0 -2
- package/dist/react-error-boundary.umd.min.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,446 +1,163 @@
|
|
|
1
|
-
|
|
2
|
-
<h1>react-error-boundary</h1>
|
|
1
|
+
# react-error-boundary
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
</div>
|
|
3
|
+
Reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component. Supports all React renderers (including React DOM and React Native). Refer to [this blog post](https://kentcdodds.com/blog/use-react-error-boundary-to-handle-errors-in-react) for more examples of how this package can be used.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
### If you like this project, [buy me a coffee](http://givebrian.coffee/).
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
[![Build Status][build-badge]][build]
|
|
11
|
-
[![Code Coverage][coverage-badge]][coverage]
|
|
12
|
-
[![version][version-badge]][package]
|
|
13
|
-
[![downloads][downloads-badge]][npmtrends]
|
|
14
|
-
[![MIT License][license-badge]][license]
|
|
15
|
-
[![PRs Welcome][prs-badge]][prs]
|
|
16
|
-
[![Code of Conduct][coc-badge]][coc]
|
|
17
|
-
<!-- prettier-ignore-end -->
|
|
7
|
+
## Getting started
|
|
18
8
|
|
|
19
|
-
|
|
9
|
+
```sh
|
|
10
|
+
# npm
|
|
11
|
+
npm install react-error-boundary
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## This solution
|
|
25
|
-
|
|
26
|
-
This component provides a simple and reusable wrapper that you can use to wrap
|
|
27
|
-
around your components. Any rendering errors in your components hierarchy can
|
|
28
|
-
then be gracefully handled.
|
|
29
|
-
|
|
30
|
-
Reading this blog post will help you understand what react-error-boundary does
|
|
31
|
-
for you:
|
|
32
|
-
[Use react-error-boundary to handle errors in React](https://kentcdodds.com/blog/use-react-error-boundary-to-handle-errors-in-react)
|
|
33
|
-
– How to simplify your React apps by handling React errors effectively with
|
|
34
|
-
react-error-boundary
|
|
35
|
-
|
|
36
|
-
## Table of Contents
|
|
37
|
-
|
|
38
|
-
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
39
|
-
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
40
|
-
|
|
41
|
-
- [Installation](#installation)
|
|
42
|
-
- [Usage](#usage)
|
|
43
|
-
- [Error Recovery](#error-recovery)
|
|
44
|
-
- [API](#api)
|
|
45
|
-
- [`ErrorBoundary` props](#errorboundary-props)
|
|
46
|
-
- [`useErrorHandler(error?: unknown)`](#useerrorhandlererror-unknown)
|
|
47
|
-
- [Issues](#issues)
|
|
48
|
-
- [🐛 Bugs](#-bugs)
|
|
49
|
-
- [💡 Feature Requests](#-feature-requests)
|
|
50
|
-
- [LICENSE](#license)
|
|
13
|
+
# yarn
|
|
14
|
+
yarn add react-error-boundary
|
|
15
|
+
```
|
|
51
16
|
|
|
52
|
-
|
|
17
|
+
## API
|
|
53
18
|
|
|
54
|
-
|
|
19
|
+
### `ErrorBoundary` component
|
|
20
|
+
Wrap an `ErrorBoundary` around other React components to "catch" errors and render a fallback UI. The component supports several ways to render a fallback (shown below).
|
|
55
21
|
|
|
56
|
-
|
|
57
|
-
|
|
22
|
+
#### `ErrorBoundary` with `fallback` prop
|
|
23
|
+
The simplest way to render a default "something went wrong" type error message.
|
|
24
|
+
```js
|
|
25
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
58
26
|
|
|
27
|
+
<ErrorBoundary fallback={<div>Something went wrong</div>}>
|
|
28
|
+
<ExampleApplication />
|
|
29
|
+
</ErrorBoundary>
|
|
59
30
|
```
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
31
|
+
#### `ErrorBoundary` with `fallbackRender` prop
|
|
32
|
+
["Render prop"](https://react.dev/reference/react/Children#calling-a-render-prop-to-customize-rendering) function responsible for returning a fallback UI based on a thrown value.
|
|
33
|
+
```js
|
|
34
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
64
35
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
its descendants too.
|
|
36
|
+
function fallbackRender({ error, resetErrorBoundary }) {
|
|
37
|
+
// Call resetErrorBoundary() to reset the error boundary and retry the render.
|
|
68
38
|
|
|
69
|
-
```jsx
|
|
70
|
-
import {ErrorBoundary} from 'react-error-boundary'
|
|
71
|
-
|
|
72
|
-
function ErrorFallback({error, resetErrorBoundary}) {
|
|
73
39
|
return (
|
|
74
40
|
<div role="alert">
|
|
75
41
|
<p>Something went wrong:</p>
|
|
76
|
-
<pre>{error.message}</pre>
|
|
77
|
-
<button onClick={resetErrorBoundary}>Try again</button>
|
|
42
|
+
<pre style={{ color: "red" }}>{error.message}</pre>
|
|
78
43
|
</div>
|
|
79
|
-
)
|
|
44
|
+
);
|
|
80
45
|
}
|
|
81
46
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
</ErrorBoundary>
|
|
91
|
-
)
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
You can react to errors (e.g. for logging) by providing an `onError` callback:
|
|
95
|
-
|
|
96
|
-
```jsx
|
|
97
|
-
import {ErrorBoundary} from 'react-error-boundary'
|
|
98
|
-
|
|
99
|
-
const myErrorHandler = (error: Error, info: {componentStack: string}) => {
|
|
100
|
-
// Do something with the error
|
|
101
|
-
// E.g. log to an error logging client here
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const ui = (
|
|
105
|
-
<ErrorBoundary FallbackComponent={ErrorFallback} onError={myErrorHandler}>
|
|
106
|
-
<ComponentThatMayError />
|
|
107
|
-
</ErrorBoundary>,
|
|
108
|
-
)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
You can also use it as a
|
|
112
|
-
[higher-order component](https://reactjs.org/docs/higher-order-components.html):
|
|
113
|
-
|
|
114
|
-
```jsx
|
|
115
|
-
import {withErrorBoundary} from 'react-error-boundary'
|
|
116
|
-
|
|
117
|
-
const ComponentWithErrorBoundary = withErrorBoundary(ComponentThatMayError, {
|
|
118
|
-
FallbackComponent: ErrorBoundaryFallbackComponent,
|
|
119
|
-
onError(error, info) {
|
|
120
|
-
// Do something with the error
|
|
121
|
-
// E.g. log to an error logging client here
|
|
122
|
-
},
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const ui = <ComponentWithErrorBoundary />
|
|
47
|
+
<ErrorBoundary
|
|
48
|
+
fallbackRender={fallbackRender}
|
|
49
|
+
onReset={(details) => {
|
|
50
|
+
// Reset the state of your app so the error doesn't happen again
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
<ExampleApplication />
|
|
54
|
+
</ErrorBoundary>;
|
|
126
55
|
```
|
|
56
|
+
#### `ErrorBoundary` with `FallbackComponent` prop
|
|
57
|
+
React component responsible for returning a fallback UI based on a thrown value.
|
|
58
|
+
```js
|
|
59
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
127
60
|
|
|
128
|
-
|
|
61
|
+
function Fallback({ error, resetErrorBoundary }) {
|
|
62
|
+
// Call resetErrorBoundary() to reset the error boundary and retry the render.
|
|
129
63
|
|
|
130
|
-
In the event of an error if you want to recover from that error and allow the
|
|
131
|
-
user to "try again" or continue with their work, you'll need a way to reset the
|
|
132
|
-
ErrorBoundary's internal state. You can do this various ways, but here's the
|
|
133
|
-
most idiomatic approach:
|
|
134
|
-
|
|
135
|
-
```jsx
|
|
136
|
-
function ErrorFallback({error, resetErrorBoundary}) {
|
|
137
64
|
return (
|
|
138
65
|
<div role="alert">
|
|
139
66
|
<p>Something went wrong:</p>
|
|
140
|
-
<pre>{error.message}</pre>
|
|
141
|
-
<button onClick={resetErrorBoundary}>Try again</button>
|
|
67
|
+
<pre style={{ color: "red" }}>{error.message}</pre>
|
|
142
68
|
</div>
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function Bomb() {
|
|
147
|
-
throw new Error('💥 CABOOM 💥')
|
|
69
|
+
);
|
|
148
70
|
}
|
|
149
71
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
resetKeys={[explode]}
|
|
159
|
-
>
|
|
160
|
-
{explode ? <Bomb /> : null}
|
|
161
|
-
</ErrorBoundary>
|
|
162
|
-
</div>
|
|
163
|
-
)
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
So, with this setup, you've got a button which when clicked will trigger an
|
|
168
|
-
error. Clicking the button again will trigger a re-render which recovers from
|
|
169
|
-
the error (we no longer render the `<Bomb />`). We also pass the `resetKeys`
|
|
170
|
-
prop which is an array of elements for the `ErrorBoundary` to check each render
|
|
171
|
-
(if there's currently an error state). If any of those elements change between
|
|
172
|
-
renders, then the `ErrorBoundary` will reset the state which will re-render the
|
|
173
|
-
children.
|
|
174
|
-
|
|
175
|
-
We have the `onReset` prop so that if the user clicks the "Try again" button we
|
|
176
|
-
have an opportunity to re-initialize our state into a good place before
|
|
177
|
-
attempting to re-render the children.
|
|
178
|
-
|
|
179
|
-
This combination allows us both the opportunity to give the user something
|
|
180
|
-
specific to do to recover from the error, and recover from the error by
|
|
181
|
-
interacting with other areas of the app that might fix things for us. It's hard
|
|
182
|
-
to describe here, but hopefully it makes sense when you apply it to your
|
|
183
|
-
specific scenario.
|
|
184
|
-
|
|
185
|
-
## API
|
|
186
|
-
|
|
187
|
-
### `ErrorBoundary` props
|
|
188
|
-
|
|
189
|
-
#### `children`
|
|
190
|
-
|
|
191
|
-
This is what you want rendered when everything's working fine. If there's an
|
|
192
|
-
error that React can handle within the children of the `ErrorBoundary`, the
|
|
193
|
-
`ErrorBoundary` will catch that and allow you to handle it gracefully.
|
|
194
|
-
|
|
195
|
-
#### `FallbackComponent`
|
|
196
|
-
|
|
197
|
-
This is a component you want rendered in the event of an error. As props it will
|
|
198
|
-
be passed the `error` and `resetErrorBoundary` (which will reset the error
|
|
199
|
-
boundary's state when called, useful for a "try again" button when used in
|
|
200
|
-
combination with the `onReset` prop).
|
|
201
|
-
|
|
202
|
-
This is required if no `fallback` or `fallbackRender` prop is provided.
|
|
203
|
-
|
|
204
|
-
#### `fallbackRender`
|
|
205
|
-
|
|
206
|
-
This is a render-prop based API that allows you to inline your error fallback UI
|
|
207
|
-
into the component that's using the `ErrorBoundary`. This is useful if you need
|
|
208
|
-
access to something that's in the scope of the component you're using.
|
|
209
|
-
|
|
210
|
-
It will be called with an object that has `error` and `resetErrorBoundary`:
|
|
211
|
-
|
|
212
|
-
```jsx
|
|
213
|
-
const ui = (
|
|
214
|
-
<ErrorBoundary
|
|
215
|
-
fallbackRender={({error, resetErrorBoundary}) => (
|
|
216
|
-
<div role="alert">
|
|
217
|
-
<div>Oh no</div>
|
|
218
|
-
<pre>{error.message}</pre>
|
|
219
|
-
<button
|
|
220
|
-
onClick={() => {
|
|
221
|
-
// this next line is why the fallbackRender is useful
|
|
222
|
-
resetComponentState()
|
|
223
|
-
// though you could accomplish this with a combination
|
|
224
|
-
// of the FallbackCallback and onReset props as well.
|
|
225
|
-
resetErrorBoundary()
|
|
226
|
-
}}
|
|
227
|
-
>
|
|
228
|
-
Try again
|
|
229
|
-
</button>
|
|
230
|
-
</div>
|
|
231
|
-
)}
|
|
232
|
-
>
|
|
233
|
-
<ComponentThatMayError />
|
|
234
|
-
</ErrorBoundary>
|
|
235
|
-
)
|
|
72
|
+
<ErrorBoundary
|
|
73
|
+
FallbackComponent={Fallback}
|
|
74
|
+
onReset={(details) => {
|
|
75
|
+
// Reset the state of your app so the error doesn't happen again
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<ExampleApplication />
|
|
79
|
+
</ErrorBoundary>;
|
|
236
80
|
```
|
|
237
81
|
|
|
238
|
-
|
|
239
|
-
around. Unfortunately, the current React Error Boundary API only supports class
|
|
240
|
-
components at the moment, so render props are the best solution we have to this
|
|
241
|
-
problem.
|
|
82
|
+
#### Logging errors with `onError`
|
|
242
83
|
|
|
243
|
-
|
|
84
|
+
```js
|
|
85
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
244
86
|
|
|
245
|
-
|
|
87
|
+
const logError = (error: Error, info: { componentStack: string }) => {
|
|
88
|
+
// Do something with the error, e.g. log to an external API
|
|
89
|
+
};
|
|
246
90
|
|
|
247
|
-
In the spirit of consistency with the `React.Suspense` component, we also
|
|
248
|
-
support a simple `fallback` prop which you can use for a generic fallback. This
|
|
249
|
-
will not be passed any props so you can't show the user anything actually useful
|
|
250
|
-
though, so it's not really recommended.
|
|
251
|
-
|
|
252
|
-
```jsx
|
|
253
91
|
const ui = (
|
|
254
|
-
<ErrorBoundary
|
|
255
|
-
<
|
|
92
|
+
<ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}>
|
|
93
|
+
<ExampleApplication />
|
|
256
94
|
</ErrorBoundary>
|
|
257
|
-
)
|
|
95
|
+
);
|
|
258
96
|
```
|
|
259
97
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
This will be called when there's been an error that the `ErrorBoundary` has
|
|
263
|
-
handled. It will be called with two arguments: `error`, `info`.
|
|
264
|
-
|
|
265
|
-
#### `onReset`
|
|
266
|
-
|
|
267
|
-
This will be called immediately before the `ErrorBoundary` resets it's internal
|
|
268
|
-
state (which will result in rendering the `children` again). You should use this
|
|
269
|
-
to ensure that re-rendering the children will not result in a repeat of the same
|
|
270
|
-
error happening again.
|
|
271
|
-
|
|
272
|
-
`onReset` will be called with whatever `resetErrorBoundary` is called with.
|
|
273
|
-
|
|
274
|
-
**Important**: `onReset` will _not_ be called when reset happens from a change
|
|
275
|
-
in `resetKeys`. Use `onResetKeysChange` for that.
|
|
98
|
+
### `useErrorBoundary` hook
|
|
99
|
+
Convenience hook for imperatively showing or dismissing error boundaries.
|
|
276
100
|
|
|
277
|
-
####
|
|
101
|
+
#### Show the nearest error boundary from an event handler
|
|
278
102
|
|
|
279
|
-
|
|
280
|
-
rendering the error. If this is the case, then you can pass `resetKeys` which is
|
|
281
|
-
an array of values. If the `ErrorBoundary` is in an error state, then it will
|
|
282
|
-
check these values each render and if they change from one render to the next,
|
|
283
|
-
then it will reset automatically (triggering a re-render of the `children`).
|
|
103
|
+
React only handles errors thrown during render or during component lifecycle methods (e.g. effects and did-mount/did-update). Errors thrown in event handlers, or after async code has run, will not be caught.
|
|
284
104
|
|
|
285
|
-
|
|
105
|
+
This hook can be used to pass those errors to the nearest error boundary:
|
|
286
106
|
|
|
287
|
-
|
|
107
|
+
```js
|
|
108
|
+
import { useErrorBoundary } from "react-error-boundary";
|
|
288
109
|
|
|
289
|
-
|
|
290
|
-
|
|
110
|
+
function Example() {
|
|
111
|
+
const { showBoundary } = useErrorBoundary();
|
|
291
112
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
React's error boundaries feature is limited in that the boundaries can only
|
|
295
|
-
handle errors thrown during React's lifecycles. To quote
|
|
296
|
-
[the React docs on Error Boundaries](https://reactjs.org/docs/error-boundaries.html):
|
|
297
|
-
|
|
298
|
-
> Error boundaries do not catch errors for:
|
|
299
|
-
>
|
|
300
|
-
> - Event handlers
|
|
301
|
-
> ([learn more](https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers))
|
|
302
|
-
> - Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
|
|
303
|
-
> - Server side rendering
|
|
304
|
-
> - Errors thrown in the error boundary itself (rather than its children)
|
|
305
|
-
|
|
306
|
-
This means you have to handle those errors yourself, but you probably would like
|
|
307
|
-
to reuse the error boundaries you worked hard on creating for those kinds of
|
|
308
|
-
errors as well. This is what `useErrorHandler` is for.
|
|
309
|
-
|
|
310
|
-
There are two ways to use `useErrorHandler`:
|
|
311
|
-
|
|
312
|
-
1. `const handleError = useErrorHandler()`: call `handleError(theError)`
|
|
313
|
-
2. `useErrorHandler(error)`: useful if you are managing the error state yourself
|
|
314
|
-
or get it from another hook.
|
|
315
|
-
|
|
316
|
-
Here's an example:
|
|
317
|
-
|
|
318
|
-
```javascript
|
|
319
|
-
import { useErrorHandler } from 'react-error-boundary'
|
|
320
|
-
|
|
321
|
-
function Greeting() {
|
|
322
|
-
const [greeting, setGreeting] = React.useState(null)
|
|
323
|
-
const handleError = useErrorHandler()
|
|
324
|
-
|
|
325
|
-
function handleSubmit(event) {
|
|
326
|
-
event.preventDefault()
|
|
327
|
-
const name = event.target.elements.name.value
|
|
113
|
+
useEffect(() => {
|
|
328
114
|
fetchGreeting(name).then(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
<button type="submit">get a greeting</button>
|
|
341
|
-
</form>
|
|
342
|
-
)
|
|
115
|
+
response => {
|
|
116
|
+
// Set data in state and re-render
|
|
117
|
+
},
|
|
118
|
+
error => {
|
|
119
|
+
// Show error boundary
|
|
120
|
+
showBoundary(error);
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Render ...
|
|
343
126
|
}
|
|
344
127
|
```
|
|
345
128
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
```javascript
|
|
350
|
-
function handleSubmit(event) {
|
|
351
|
-
event.preventDefault()
|
|
352
|
-
const name = event.target.elements.name.value
|
|
353
|
-
fetchGreeting(name).then(
|
|
354
|
-
newGreeting => setGreeting(newGreeting),
|
|
355
|
-
error => handleError(error),
|
|
356
|
-
)
|
|
357
|
-
}
|
|
358
|
-
```
|
|
129
|
+
#### Dismiss the nearest error boundary
|
|
130
|
+
A fallback component can use this hook to request the nearest error boundary retry the render that original failed.
|
|
359
131
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
```javascript
|
|
363
|
-
import { useErrorHandler } from 'react-error-boundary'
|
|
364
|
-
|
|
365
|
-
function Greeting() {
|
|
366
|
-
const [name, setName] = React.useState('')
|
|
367
|
-
const {greeting, error} = useGreeting(name)
|
|
368
|
-
useErrorHandler(error)
|
|
369
|
-
|
|
370
|
-
function handleSubmit(event) {
|
|
371
|
-
event.preventDefault()
|
|
372
|
-
const name = event.target.elements.name.value
|
|
373
|
-
setName(name)
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return greeting ? (
|
|
377
|
-
<div>{greeting}</div>
|
|
378
|
-
) : (
|
|
379
|
-
<form onSubmit={handleSubmit}>
|
|
380
|
-
<label>Name</label>
|
|
381
|
-
<input id="name" />
|
|
382
|
-
<button type="submit">get a greeting</button>
|
|
383
|
-
</form>
|
|
384
|
-
)
|
|
385
|
-
}
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
In this case, if the `error` is ever set to a truthy value, then it will be
|
|
389
|
-
propagated to the nearest error boundary.
|
|
132
|
+
```js
|
|
133
|
+
import { useErrorBoundary } from "react-error-boundary";
|
|
390
134
|
|
|
391
|
-
|
|
135
|
+
function ErrorFallback({ error }) {
|
|
136
|
+
const { resetBoundary } = useErrorBoundary();
|
|
392
137
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
138
|
+
return (
|
|
139
|
+
<div role="alert">
|
|
140
|
+
<p>Something went wrong:</p>
|
|
141
|
+
<pre style={{ color: "red" }}>{error.message}</pre>
|
|
142
|
+
<button onClick={resetBoundary}>Try again</button>
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
399
146
|
```
|
|
400
147
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
## Issues
|
|
405
|
-
|
|
406
|
-
_Looking to contribute? Look for the [Good First Issue][good-first-issue]
|
|
407
|
-
label._
|
|
148
|
+
### `withErrorBoundary` HOC
|
|
149
|
+
This package can also be used as a [higher-order component](https://legacy.reactjs.org/docs/higher-order-components.html) that accepts all of the same props as above:
|
|
408
150
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
Please file an issue for bugs, missing documentation, or unexpected behavior.
|
|
412
|
-
|
|
413
|
-
[**See Bugs**][bugs]
|
|
414
|
-
|
|
415
|
-
### 💡 Feature Requests
|
|
416
|
-
|
|
417
|
-
Please file an issue to suggest new features. Vote on feature requests by adding
|
|
418
|
-
a 👍. This helps maintainers prioritize what to work on.
|
|
419
|
-
|
|
420
|
-
[**See Feature Requests**][requests]
|
|
421
|
-
|
|
422
|
-
## LICENSE
|
|
151
|
+
```js
|
|
152
|
+
import {withErrorBoundary} from 'react-error-boundary'
|
|
423
153
|
|
|
424
|
-
|
|
154
|
+
const ComponentWithErrorBoundary = withErrorBoundary(ExampleComponent, {
|
|
155
|
+
fallback: <div>Something went wrong</div>,
|
|
156
|
+
onError(error, info) {
|
|
157
|
+
// Do something with the error
|
|
158
|
+
// E.g. log to an error logging client here
|
|
159
|
+
},
|
|
160
|
+
})
|
|
425
161
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
[node]: https://nodejs.org
|
|
429
|
-
[build-badge]: https://img.shields.io/github/workflow/status/bvaughn/react-error-boundary/validate?logo=github&style=flat-square
|
|
430
|
-
[build]: https://github.com/bvaughn/react-error-boundary/actions?query=workflow%3Avalidate
|
|
431
|
-
[coverage-badge]: https://img.shields.io/codecov/c/github/bvaughn/react-error-boundary.svg?style=flat-square
|
|
432
|
-
[coverage]: https://codecov.io/github/bvaughn/react-error-boundary
|
|
433
|
-
[version-badge]: https://img.shields.io/npm/v/react-error-boundary.svg?style=flat-square
|
|
434
|
-
[package]: https://www.npmjs.com/package/react-error-boundary
|
|
435
|
-
[downloads-badge]: https://img.shields.io/npm/dm/react-error-boundary.svg?style=flat-square
|
|
436
|
-
[npmtrends]: https://www.npmtrends.com/react-error-boundary
|
|
437
|
-
[license-badge]: https://img.shields.io/npm/l/react-error-boundary.svg?style=flat-square
|
|
438
|
-
[license]: https://github.com/bvaughn/react-error-boundary/blob/master/LICENSE
|
|
439
|
-
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
|
440
|
-
[prs]: https://makeapullrequest.com
|
|
441
|
-
[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
|
|
442
|
-
[coc]: https://github.com/bvaughn/react-error-boundary/blob/master/CODE_OF_CONDUCT.md
|
|
443
|
-
[bugs]: https://github.com/bvaughn/react-error-boundary/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Acreated-desc+label%3Abug
|
|
444
|
-
[requests]: https://github.com/bvaughn/react-error-boundary/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement
|
|
445
|
-
[good-first-issue]: https://github.com/bvaughn/react-error-boundary/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement+label%3A%22good+first+issue%22
|
|
446
|
-
<!-- prettier-ignore-end -->
|
|
162
|
+
// Can be rendered as <ComponentWithErrorBoundary {...props} />
|
|
163
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Component, ComponentType, FunctionComponent, ReactElement, ReactNode, ErrorInfo, PropsWithChildren, PropsWithRef } from "react";
|
|
2
|
+
export type ErrorBoundaryContextType = {
|
|
3
|
+
didCatch: boolean;
|
|
4
|
+
error: any;
|
|
5
|
+
resetErrorBoundary: (...args: any[]) => void;
|
|
6
|
+
};
|
|
7
|
+
export const ErrorBoundaryContext: import("react").Context<ErrorBoundaryContextType | null>;
|
|
8
|
+
declare function FallbackRender(props: FallbackProps): ReactNode;
|
|
9
|
+
export type FallbackProps = {
|
|
10
|
+
error: any;
|
|
11
|
+
resetErrorBoundary: (...args: any[]) => void;
|
|
12
|
+
};
|
|
13
|
+
type ErrorBoundarySharedProps = {
|
|
14
|
+
onError?: (error: Error, info: {
|
|
15
|
+
componentStack: string;
|
|
16
|
+
}) => void;
|
|
17
|
+
onReset?: (details: {
|
|
18
|
+
reason: "imperative-api";
|
|
19
|
+
args: any[];
|
|
20
|
+
} | {
|
|
21
|
+
reason: "keys";
|
|
22
|
+
prev: any[] | undefined;
|
|
23
|
+
next: any[] | undefined;
|
|
24
|
+
}) => void;
|
|
25
|
+
resetKeys?: any[];
|
|
26
|
+
};
|
|
27
|
+
export type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
|
|
28
|
+
fallback?: never;
|
|
29
|
+
FallbackComponent: ComponentType<FallbackProps>;
|
|
30
|
+
fallbackRender?: never;
|
|
31
|
+
};
|
|
32
|
+
export type ErrorBoundaryPropsWithRender = ErrorBoundarySharedProps & {
|
|
33
|
+
fallback?: never;
|
|
34
|
+
FallbackComponent?: never;
|
|
35
|
+
fallbackRender: typeof FallbackRender;
|
|
36
|
+
};
|
|
37
|
+
export type ErrorBoundaryPropsWithFallback = ErrorBoundarySharedProps & {
|
|
38
|
+
fallback: ReactElement<unknown, string | FunctionComponent | typeof Component> | null;
|
|
39
|
+
FallbackComponent?: never;
|
|
40
|
+
fallbackRender?: never;
|
|
41
|
+
};
|
|
42
|
+
export type ErrorBoundaryProps = ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender;
|
|
43
|
+
type ErrorBoundaryState = {
|
|
44
|
+
didCatch: boolean;
|
|
45
|
+
error: any;
|
|
46
|
+
};
|
|
47
|
+
export class ErrorBoundary extends Component<PropsWithRef<PropsWithChildren<ErrorBoundaryProps>>, ErrorBoundaryState> {
|
|
48
|
+
state: ErrorBoundaryState;
|
|
49
|
+
static getDerivedStateFromError(error: Error): {
|
|
50
|
+
didCatch: boolean;
|
|
51
|
+
error: Error;
|
|
52
|
+
};
|
|
53
|
+
resetErrorBoundary: (...args: any[]) => void;
|
|
54
|
+
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
55
|
+
componentDidUpdate(prevProps: ErrorBoundaryProps, prevState: ErrorBoundaryState): void;
|
|
56
|
+
render(): import("react").FunctionComponentElement<import("react").ProviderProps<import("ErrorBoundaryContext").ErrorBoundaryContextType | null>>;
|
|
57
|
+
}
|
|
58
|
+
export type UseErrorBoundaryApi<Error> = {
|
|
59
|
+
resetBoundary: () => void;
|
|
60
|
+
showBoundary: (error: Error) => void;
|
|
61
|
+
};
|
|
62
|
+
export function useErrorBoundary<Error = any>(): UseErrorBoundaryApi<Error>;
|
|
63
|
+
export function withErrorBoundary<Props extends Object>(Component: ComponentType<Props>, errorBoundaryProps: ErrorBoundaryProps): ComponentType<Props>;
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=react-error-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";AAEA,uCAAuC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,GAAG,CAAC;IACX,kBAAkB,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAC9C,CAAC;AAEF,OAAO,MAAM,8EACyC,CAAC;ACDvD,gCAAgC,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;AAEjE,4BAA4B;IAC1B,KAAK,EAAE,GAAG,CAAC;IACX,kBAAkB,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAC9C,CAAC;AAEF,gCAAgC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,CACR,OAAO,EACH;QAAE,MAAM,EAAE,gBAAgB,CAAC;QAAC,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,GACzC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,CAAA;KAAE,KACrE,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;CACnB,CAAC;AAEF,8CAA8C,wBAAwB,GAAG;IACvE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,iBAAiB,EAAE,cAAc,aAAa,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,KAAK,CAAC;CACxB,CAAC;AAEF,2CAA2C,wBAAwB,GAAG;IACpE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAC1B,cAAc,EAAE,qBAAqB,CAAC;CACvC,CAAC;AAEF,6CAA6C,wBAAwB,GAAG;IACtE,QAAQ,EAAE,aACR,OAAO,EACP,MAAM,GAAG,iBAAiB,GAAG,gBAAgB,CAC9C,GAAG,IAAI,CAAC;IACT,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAC1B,cAAc,CAAC,EAAE,KAAK,CAAC;CACxB,CAAC;AAEF,iCACI,8BAA8B,GAC9B,+BAA+B,GAC/B,4BAA4B,CAAC;ACtCjC,0BAA0B;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC;AAO5D,0BAA2B,SAAQ,UACjC,aAAa,kBAAkB,kBAAkB,CAAC,CAAC,EACnD,kBAAkB,CACnB;IACC,KAAK,qBAAgB;IAErB,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK;;;;IAI5C,kBAAkB,YAAa,GAAG,EAAE,UAWlC;IAEF,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS;IAI/C,kBAAkB,CAChB,SAAS,EAAE,kBAAkB,EAC7B,SAAS,EAAE,kBAAkB;IAyB/B,MAAM;CAsCP;AE1GD,gCAAgC,KAAK,IAAI;IACvC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,iCAAiC,KAAK,GAAG,GAAG,KAAK,oBAAoB,KAAK,CAAC,CAiC1E;ACtCD,kCAAkC,KAAK,SAAS,MAAM,EACpD,SAAS,EAAE,cAAc,KAAK,CAAC,EAC/B,kBAAkB,EAAE,kBAAkB,GACrC,cAAc,KAAK,CAAC,CActB","sources":["src/src/ErrorBoundaryContext.ts","src/src/types.ts","src/src/ErrorBoundary.ts","src/src/assertErrorBoundaryContext.ts","src/src/useErrorBoundary.ts","src/src/withErrorBoundary.ts","src/src/index.ts","src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,"export * from \"./ErrorBoundary\";\nexport * from \"./ErrorBoundaryContext\";\nexport * from \"./useErrorBoundary\";\nexport * from \"./withErrorBoundary\";\n\n// TypeScript types\nexport * from \"./types\";\n"],"names":[],"version":3,"file":"react-error-boundary.d.ts.map"}
|