react-error-boundary 6.0.0 → 6.0.2

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 CHANGED
@@ -1,6 +1,6 @@
1
- # react-error-boundary
1
+ <img src="https://react-error-boundary-lib.vercel.app/og.svg" alt="react-error-boundary logo" width="400" height="210" />
2
2
 
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).
3
+ `react-error-boundary`: 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).
4
4
 
5
5
  ### If you like this project, 🎉 [become a sponsor](https://github.com/sponsors/bvaughn/) or ☕ [buy me a coffee](http://givebrian.coffee/)
6
6
 
@@ -17,171 +17,93 @@ pnpm add react-error-boundary
17
17
  yarn add react-error-boundary
18
18
  ```
19
19
 
20
- ## API
21
-
22
- ### `ErrorBoundary` component
23
- Wrap an `ErrorBoundary` component around other React components to "catch" errors and render a fallback UI. The component supports several ways to render a fallback (as shown below).
24
-
25
- > **Note** `ErrorBoundary` is a _client_ component. You can only pass props to it that are serializeable or use it in files that have a `"use client";` directive.
26
-
27
- #### `ErrorBoundary` with `fallback` prop
28
- The simplest way to render a default "something went wrong" type of error message.
29
- ```js
30
- "use client";
31
-
32
- import { ErrorBoundary } from "react-error-boundary";
33
-
34
- <ErrorBoundary fallback={<div>Something went wrong</div>}>
35
- <ExampleApplication />
36
- </ErrorBoundary>
37
- ```
38
- #### `ErrorBoundary` with `fallbackRender` prop
39
- ["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.
40
- ```js
41
- "use client";
42
-
43
- import { ErrorBoundary } from "react-error-boundary";
44
-
45
- function fallbackRender({ error, resetErrorBoundary }) {
46
- // Call resetErrorBoundary() to reset the error boundary and retry the render.
47
-
48
- return (
49
- <div role="alert">
50
- <p>Something went wrong:</p>
51
- <pre style={{ color: "red" }}>{error.message}</pre>
52
- </div>
53
- );
54
- }
55
-
56
- <ErrorBoundary
57
- fallbackRender={fallbackRender}
58
- onReset={(details) => {
59
- // Reset the state of your app so the error doesn't happen again
60
- }}
61
- >
62
- <ExampleApplication />
63
- </ErrorBoundary>;
64
- ```
65
- #### `ErrorBoundary` with `FallbackComponent` prop
66
- React component responsible for returning a fallback UI based on a thrown value.
67
- ```js
68
- "use client";
69
-
70
- import { ErrorBoundary } from "react-error-boundary";
71
-
72
- function Fallback({ error, resetErrorBoundary }) {
73
- // Call resetErrorBoundary() to reset the error boundary and retry the render.
74
-
75
- return (
76
- <div role="alert">
77
- <p>Something went wrong:</p>
78
- <pre style={{ color: "red" }}>{error.message}</pre>
79
- </div>
80
- );
81
- }
82
-
83
- <ErrorBoundary
84
- FallbackComponent={Fallback}
85
- onReset={(details) => {
86
- // Reset the state of your app so the error doesn't happen again
87
- }}
88
- >
89
- <ExampleApplication />
90
- </ErrorBoundary>;
91
- ```
92
-
93
- #### Logging errors with `onError`
94
-
95
- ```js
96
- "use client";
97
-
98
- import { ErrorBoundary } from "react-error-boundary";
99
-
100
- const logError = (error: Error, info: { componentStack: string }) => {
101
- // Do something with the error, e.g. log to an external API
102
- };
103
-
104
- const ui = (
105
- <ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}>
106
- <ExampleApplication />
107
- </ErrorBoundary>
108
- );
109
- ```
110
-
111
- ### `useErrorBoundary` hook
112
- Convenience hook for imperatively showing or dismissing error boundaries.
113
-
114
- #### Show the nearest error boundary from an event handler
115
-
116
- 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.
20
+ ## FAQs
117
21
 
118
- This hook can be used to pass those errors to the nearest error boundary:
22
+ Frequently asked questions can be found [here](https://react-error-boundary-lib.vercel.app/common-questions).
119
23
 
120
- ```js
121
- "use client";
122
-
123
- import { useErrorBoundary } from "react-error-boundary";
124
-
125
- function Example() {
126
- const { showBoundary } = useErrorBoundary();
127
-
128
- useEffect(() => {
129
- fetchGreeting(name).then(
130
- response => {
131
- // Set data in state and re-render
132
- },
133
- error => {
134
- // Show error boundary
135
- showBoundary(error);
136
- }
137
- );
138
- });
139
-
140
- // Render ...
141
- }
142
- ```
143
-
144
- #### Dismiss the nearest error boundary
145
- A fallback component can use this hook to request the nearest error boundary retry the render that originally failed.
146
-
147
- ```js
148
- "use client";
149
-
150
- import { useErrorBoundary } from "react-error-boundary";
151
-
152
- function ErrorFallback({ error }) {
153
- const { resetBoundary } = useErrorBoundary();
154
-
155
- return (
156
- <div role="alert">
157
- <p>Something went wrong:</p>
158
- <pre style={{ color: "red" }}>{error.message}</pre>
159
- <button onClick={resetBoundary}>Try again</button>
160
- </div>
161
- );
162
- }
163
- ```
164
-
165
- ### `withErrorBoundary` HOC
166
- 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:
167
-
168
- ```js
169
- "use client";
170
-
171
- import {withErrorBoundary} from 'react-error-boundary'
172
-
173
- const ComponentWithErrorBoundary = withErrorBoundary(ExampleComponent, {
174
- fallback: <div>Something went wrong</div>,
175
- onError(error, info) {
176
- // Do something with the error
177
- // E.g. log to an error logging client here
178
- },
179
- })
180
-
181
- // Can be rendered as <ComponentWithErrorBoundary {...props} />
182
- ```
24
+ ## API
183
25
 
184
- ---
26
+ ### ErrorBoundary
27
+
28
+ <!-- ErrorBoundary:description:begin -->
29
+ A reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.
30
+ Wrap this component around other React components to "catch" errors and render a fallback UI.
31
+
32
+ This package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),
33
+ so it has all of the advantages and constraints of that API.
34
+ This means that it can't catch errors during:
35
+ - Server side rendering</li>
36
+ - Event handlers
37
+ - Asynchronous code (including effects)
38
+
39
+ ℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.
40
+ Refer to the documentation to determine which is best for your application.
41
+
42
+ ℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `"use client";` directive.
43
+ <!-- ErrorBoundary:description:end -->
44
+
45
+ #### Required props
46
+
47
+ <!-- ErrorBoundary:required-props:begin -->
48
+ None
49
+ <!-- ErrorBoundary:required-props:end -->
50
+
51
+ #### Optional props
52
+
53
+ <!-- ErrorBoundary:optional-props:begin -->
54
+
55
+ <table>
56
+ <thead>
57
+ <tr>
58
+ <th>Name</th>
59
+ <th>Description</th>
60
+ </tr>
61
+ </thead>
62
+ <tbody>
63
+ <tr>
64
+ <td>onError</td>
65
+ <td><p>Optional callback to enable e.g. logging error information to a server.
66
+ @param error Error that was thrown
67
+ @param info React &quot;component stack&quot; identifying where the error was thrown</p>
68
+ </td>
69
+ </tr>
70
+ <tr>
71
+ <td>onReset</td>
72
+ <td><p>Optional callback to to be notified when an error boundary is &quot;reset&quot; so React can retry the failed render.</p>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>resetKeys</td>
77
+ <td><p>When changed, these keys will reset a triggered error boundary.
78
+ This can be useful when an error condition may be tied to some specific state (that can be uniquely identified by key).
79
+ See the the documentation for examples of how to use this prop.</p>
80
+ </td>
81
+ </tr>
82
+ <tr>
83
+ <td>fallback</td>
84
+ <td><p>Static content to render in place of an error if one is thrown.</p>
85
+ <pre><code class="language-tsx">&lt;ErrorBoundary fallback={&lt;div class=&quot;text-red&quot;&gt;Something went wrong&lt;/div&gt;} /&gt;
86
+ </code></pre>
87
+ </td>
88
+ </tr>
89
+ <tr>
90
+ <td>FallbackComponent</td>
91
+ <td><p>React component responsible for returning a fallback UI based on a thrown value.</p>
92
+ <pre><code class="language-tsx">&lt;ErrorBoundary FallbackComponent={Fallback} /&gt;
93
+ </code></pre>
94
+ </td>
95
+ </tr>
96
+ <tr>
97
+ <td>fallbackRender</td>
98
+ <td><p><a href="https://react.dev/reference/react/Children#calling-a-render-prop-to-customize-rendering">Render prop</a> function responsible for returning a fallback UI based on a thrown value.</p>
99
+ <pre><code class="language-tsx">&lt;ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) =&gt; &lt;div&gt;...&lt;/div&gt;} /&gt;
100
+ </code></pre>
101
+ </td>
102
+ </tr>
103
+ </tbody>
104
+ </table>
105
+
106
+ <!-- ErrorBoundary:optional-props:end -->
185
107
 
186
108
  # FAQ
187
109
  ## `ErrorBoundary` cannot be used as a JSX component
@@ -0,0 +1,2 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react"),c=s.createContext(null),u={didCatch:!1,error:null};class l extends s.Component{constructor(e){super(e),this.resetErrorBoundary=this.resetErrorBoundary.bind(this),this.state=u}static getDerivedStateFromError(e){return{didCatch:!0,error:e}}resetErrorBoundary(...e){const{error:t}=this.state;t!==null&&(this.props.onReset?.({args:e,reason:"imperative-api"}),this.setState(u))}componentDidCatch(e,t){this.props.onError?.(e,t)}componentDidUpdate(e,t){const{didCatch:o}=this.state,{resetKeys:n}=this.props;o&&t.error!==null&&y(e.resetKeys,n)&&(this.props.onReset?.({next:n,prev:e.resetKeys,reason:"keys"}),this.setState(u))}render(){const{children:e,fallbackRender:t,FallbackComponent:o,fallback:n}=this.props,{didCatch:a,error:i}=this.state;let d=e;if(a){const h={error:i,resetErrorBoundary:this.resetErrorBoundary};if(typeof t=="function")d=t(h);else if(o)d=s.createElement(o,h);else if(n!==void 0)d=n;else throw i}return s.createElement(c.Provider,{value:{didCatch:a,error:i,resetErrorBoundary:this.resetErrorBoundary}},d)}}function y(r=[],e=[]){return r.length!==e.length||r.some((t,o)=>!Object.is(t,e[o]))}function E(r){return r!==null&&typeof r=="object"&&"didCatch"in r&&typeof r.didCatch=="boolean"&&"error"in r&&"resetErrorBoundary"in r&&typeof r.resetErrorBoundary=="function"}function f(r){if(!E(r))throw new Error("ErrorBoundaryContext not found")}function p(){const r=s.useContext(c);f(r);const{error:e,resetErrorBoundary:t}=r,[o,n]=s.useState({error:null,hasError:!1}),a=s.useMemo(()=>({error:e,resetBoundary:()=>{t(),n({error:null,hasError:!1})},showBoundary:i=>n({error:i,hasError:!0})}),[e,t]);if(o.hasError)throw o.error;return a}function B(r,e){const t=s.forwardRef((n,a)=>s.createElement(l,e,s.createElement(r,{...n,ref:a}))),o=r.displayName||r.name||"Unknown";return t.displayName=`withErrorBoundary(${o})`,t}exports.ErrorBoundary=l;exports.ErrorBoundaryContext=c;exports.useErrorBoundary=p;exports.withErrorBoundary=B;
2
+ //# sourceMappingURL=react-error-boundary.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-error-boundary.cjs","sources":["../lib/context/ErrorBoundaryContext.ts","../lib/components/ErrorBoundary.tsx","../lib/utils/isErrorBoundaryContext.ts","../lib/utils/assertErrorBoundaryContext.ts","../lib/hooks/useErrorBoundary.ts","../lib/utils/withErrorBoundary.ts"],"sourcesContent":["import { createContext } from \"react\";\n\nexport type ErrorBoundaryContextType = {\n didCatch: boolean;\n error: Error | null;\n resetErrorBoundary: (...args: unknown[]) => void;\n};\n\nexport const ErrorBoundaryContext =\n createContext<ErrorBoundaryContextType | null>(null);\n","import { Component, createElement, type ErrorInfo } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport type { ErrorBoundaryProps, FallbackProps } from \"../types\";\n\nconst isDevelopment = import.meta.env.DEV;\n\ntype ErrorBoundaryState =\n | {\n didCatch: true;\n error: Error;\n }\n | {\n didCatch: false;\n error: null;\n };\n\nconst initialState: ErrorBoundaryState = {\n didCatch: false,\n error: null,\n};\n\n/**\n * A reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.\n * Wrap this component around other React components to \"catch\" errors and render a fallback UI.\n *\n * This package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),\n * so it has all of the advantages and constraints of that API.\n * This means that it can't catch errors during:\n * - Server side rendering</li>\n * - Event handlers\n * - Asynchronous code (including effects)\n *\n * ℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.\n * Refer to the documentation to determine which is best for your application.\n *\n * ℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `\"use client\";` directive.\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.resetErrorBoundary = this.resetErrorBoundary.bind(this);\n this.state = initialState;\n }\n\n static getDerivedStateFromError(error: Error) {\n return { didCatch: true, error };\n }\n\n resetErrorBoundary(...args: unknown[]) {\n const { error } = this.state;\n\n if (error !== null) {\n this.props.onReset?.({\n args,\n reason: \"imperative-api\",\n });\n\n this.setState(initialState);\n }\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n this.props.onError?.(error, info);\n }\n\n componentDidUpdate(\n prevProps: ErrorBoundaryProps,\n prevState: ErrorBoundaryState,\n ) {\n const { didCatch } = this.state;\n const { resetKeys } = this.props;\n\n // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,\n // we'd end up resetting the error boundary immediately.\n // This would likely trigger a second error to be thrown.\n // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.\n\n if (\n didCatch &&\n prevState.error !== null &&\n hasArrayChanged(prevProps.resetKeys, resetKeys)\n ) {\n this.props.onReset?.({\n next: resetKeys,\n prev: prevProps.resetKeys,\n reason: \"keys\",\n });\n\n this.setState(initialState);\n }\n }\n\n render() {\n const { children, fallbackRender, FallbackComponent, fallback } =\n this.props;\n const { didCatch, error } = this.state;\n\n let childToRender = children;\n\n if (didCatch) {\n const props: FallbackProps = {\n error,\n resetErrorBoundary: this.resetErrorBoundary,\n };\n\n if (typeof fallbackRender === \"function\") {\n childToRender = fallbackRender(props);\n } else if (FallbackComponent) {\n childToRender = createElement(FallbackComponent, props);\n } else if (fallback !== undefined) {\n childToRender = fallback;\n } else {\n if (isDevelopment) {\n console.error(\n \"react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop\",\n );\n }\n\n throw error;\n }\n }\n\n return createElement(\n ErrorBoundaryContext.Provider,\n {\n value: {\n didCatch,\n error,\n resetErrorBoundary: this.resetErrorBoundary,\n },\n },\n childToRender,\n );\n }\n}\n\nfunction hasArrayChanged(a: unknown[] = [], b: unknown[] = []) {\n return (\n a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]))\n );\n}\n","import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\n\nexport function isErrorBoundaryContext(\n value: unknown,\n): value is ErrorBoundaryContextType {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"didCatch\" in value &&\n typeof value.didCatch === \"boolean\" &&\n \"error\" in value &&\n \"resetErrorBoundary\" in value &&\n typeof value.resetErrorBoundary === \"function\"\n );\n}\n","import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\nimport { isErrorBoundaryContext } from \"./isErrorBoundaryContext\";\n\nexport function assertErrorBoundaryContext(\n value: unknown,\n): asserts value is ErrorBoundaryContextType {\n if (!isErrorBoundaryContext(value)) {\n throw new Error(\"ErrorBoundaryContext not found\");\n }\n}\n","import { useContext, useMemo, useState } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport { assertErrorBoundaryContext } from \"../utils/assertErrorBoundaryContext\";\n\ntype UseErrorBoundaryState =\n | { error: Error; hasError: true }\n | { error: null; hasError: false };\n\nexport type UseErrorBoundaryApi = {\n error: Error | null;\n resetBoundary: () => void;\n showBoundary: (error: Error) => void;\n};\n\n/**\n * Convenience hook for imperatively showing or dismissing error boundaries.\n *\n * ⚠️ This hook must only be used within an `ErrorBoundary` subtree.\n */\nexport function useErrorBoundary(): {\n /**\n * The currently visible `Error` (if one has been thrown).\n */\n error: Error | null;\n\n /**\n * Method to reset and retry the nearest active error boundary (if one is active).\n */\n resetBoundary: () => void;\n\n /**\n * Trigger the nearest error boundary to display the error provided.\n *\n * ℹ️ React only handles errors thrown during render or during component lifecycle methods (e.g. effects and did-mount/did-update).\n * Errors thrown in event handlers, or after async code has run, will not be caught.\n * This method is a way to imperatively trigger an error boundary during these phases.\n */\n showBoundary: (error: Error) => void;\n} {\n const context = useContext(ErrorBoundaryContext);\n\n assertErrorBoundaryContext(context);\n\n const { error, resetErrorBoundary } = context;\n\n const [state, setState] = useState<UseErrorBoundaryState>({\n error: null,\n hasError: false,\n });\n\n const memoized = useMemo(\n () => ({\n error,\n resetBoundary: () => {\n resetErrorBoundary();\n setState({ error: null, hasError: false });\n },\n showBoundary: (error: Error) =>\n setState({\n error,\n hasError: true,\n }),\n }),\n [error, resetErrorBoundary],\n );\n\n if (state.hasError) {\n throw state.error;\n }\n\n return memoized;\n}\n","import {\n createElement,\n forwardRef,\n type ComponentClass,\n type ComponentType,\n} from \"react\";\nimport { ErrorBoundary } from \"../components/ErrorBoundary\";\nimport type { ErrorBoundaryProps } from \"../types\";\n\nexport function withErrorBoundary<\n Type extends ComponentClass<unknown>,\n Props extends object,\n>(Component: ComponentType<Props>, errorBoundaryProps: ErrorBoundaryProps) {\n const Wrapped = forwardRef<InstanceType<Type>, Props>((props, ref) =>\n createElement(\n ErrorBoundary,\n errorBoundaryProps,\n createElement(Component, { ...props, ref } as Props),\n ),\n );\n\n // Format for display in DevTools\n const name = Component.displayName || Component.name || \"Unknown\";\n Wrapped.displayName = `withErrorBoundary(${name})`;\n\n return Wrapped;\n}\n"],"names":["ErrorBoundaryContext","createContext","initialState","ErrorBoundary","Component","props","error","args","info","prevProps","prevState","didCatch","resetKeys","hasArrayChanged","children","fallbackRender","FallbackComponent","fallback","childToRender","createElement","a","b","item","index","isErrorBoundaryContext","value","assertErrorBoundaryContext","useErrorBoundary","context","useContext","resetErrorBoundary","state","setState","useState","memoized","useMemo","withErrorBoundary","errorBoundaryProps","Wrapped","forwardRef","ref","name"],"mappings":"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"}
@@ -1,2 +1,165 @@
1
- export * from "./declarations/src/index.js";
2
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QtZXJyb3ItYm91bmRhcnkuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4vZGVjbGFyYXRpb25zL3NyYy9pbmRleC5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIn0=
1
+ import { Component } from 'react';
2
+ import { ComponentClass } from 'react';
3
+ import { ComponentType } from 'react';
4
+ import { Context } from 'react';
5
+ import { ErrorInfo } from 'react';
6
+ import { ForwardRefExoticComponent } from 'react';
7
+ import { FunctionComponentElement } from 'react';
8
+ import { PropsWithChildren } from 'react';
9
+ import { PropsWithoutRef } from 'react';
10
+ import { ProviderProps } from 'react';
11
+ import { ReactNode } from 'react';
12
+ import { RefAttributes } from 'react';
13
+
14
+ /**
15
+ * A reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.
16
+ * Wrap this component around other React components to "catch" errors and render a fallback UI.
17
+ *
18
+ * This package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),
19
+ * so it has all of the advantages and constraints of that API.
20
+ * This means that it can't catch errors during:
21
+ * - Server side rendering</li>
22
+ * - Event handlers
23
+ * - Asynchronous code (including effects)
24
+ *
25
+ * ℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.
26
+ * Refer to the documentation to determine which is best for your application.
27
+ *
28
+ * ℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `"use client";` directive.
29
+ */
30
+ export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
31
+ constructor(props: ErrorBoundaryProps);
32
+ static getDerivedStateFromError(error: Error): {
33
+ didCatch: boolean;
34
+ error: Error;
35
+ };
36
+ resetErrorBoundary(...args: unknown[]): void;
37
+ componentDidCatch(error: Error, info: ErrorInfo): void;
38
+ componentDidUpdate(prevProps: ErrorBoundaryProps, prevState: ErrorBoundaryState): void;
39
+ render(): FunctionComponentElement<ProviderProps<ErrorBoundaryContextType | null>>;
40
+ }
41
+
42
+ export declare const ErrorBoundaryContext: Context<ErrorBoundaryContextType | null>;
43
+
44
+ export declare type ErrorBoundaryContextType = {
45
+ didCatch: boolean;
46
+ error: Error | null;
47
+ resetErrorBoundary: (...args: unknown[]) => void;
48
+ };
49
+
50
+ export declare type ErrorBoundaryProps = ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender;
51
+
52
+ export declare type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
53
+ fallback?: never;
54
+ /**
55
+ * React component responsible for returning a fallback UI based on a thrown value.
56
+ *
57
+ * ```tsx
58
+ * <ErrorBoundary FallbackComponent={Fallback} />
59
+ * ```
60
+ */
61
+ FallbackComponent: ComponentType<FallbackProps>;
62
+ fallbackRender?: never;
63
+ };
64
+
65
+ export declare type ErrorBoundaryPropsWithFallback = ErrorBoundarySharedProps & {
66
+ /**
67
+ * Static content to render in place of an error if one is thrown.
68
+ *
69
+ * ```tsx
70
+ * <ErrorBoundary fallback={<div class="text-red">Something went wrong</div>} />
71
+ * ```
72
+ */
73
+ fallback: ReactNode;
74
+ FallbackComponent?: never;
75
+ fallbackRender?: never;
76
+ };
77
+
78
+ export declare type ErrorBoundaryPropsWithRender = ErrorBoundarySharedProps & {
79
+ fallback?: never;
80
+ FallbackComponent?: never;
81
+ /**
82
+ * [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.
83
+ *
84
+ * ```tsx
85
+ * <ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) => <div>...</div>} />
86
+ * ```
87
+ */
88
+ fallbackRender: (props: FallbackProps) => ReactNode;
89
+ };
90
+
91
+ declare type ErrorBoundarySharedProps = PropsWithChildren<{
92
+ /**
93
+ * Optional callback to enable e.g. logging error information to a server.
94
+ *
95
+ * @param error Error that was thrown
96
+ * @param info React "component stack" identifying where the error was thrown
97
+ */
98
+ onError?: (error: Error, info: ErrorInfo) => void;
99
+ /**
100
+ * Optional callback to to be notified when an error boundary is "reset" so React can retry the failed render.
101
+ */
102
+ onReset?: (details: {
103
+ reason: "imperative-api";
104
+ args: unknown[];
105
+ } | {
106
+ reason: "keys";
107
+ prev: unknown[] | undefined;
108
+ next: unknown[] | undefined;
109
+ }) => void;
110
+ /**
111
+ * When changed, these keys will reset a triggered error boundary.
112
+ * This can be useful when an error condition may be tied to some specific state (that can be uniquely identified by key).
113
+ * See the the documentation for examples of how to use this prop.
114
+ */
115
+ resetKeys?: unknown[];
116
+ }>;
117
+
118
+ declare type ErrorBoundaryState = {
119
+ didCatch: true;
120
+ error: Error;
121
+ } | {
122
+ didCatch: false;
123
+ error: null;
124
+ };
125
+
126
+ export declare type FallbackProps = {
127
+ error: Error;
128
+ resetErrorBoundary: (...args: unknown[]) => void;
129
+ };
130
+
131
+ export declare type OnErrorCallback = (error: Error, info: ErrorInfo) => void;
132
+
133
+ /**
134
+ * Convenience hook for imperatively showing or dismissing error boundaries.
135
+ *
136
+ * ⚠️ This hook must only be used within an `ErrorBoundary` subtree.
137
+ */
138
+ export declare function useErrorBoundary(): {
139
+ /**
140
+ * The currently visible `Error` (if one has been thrown).
141
+ */
142
+ error: Error | null;
143
+ /**
144
+ * Method to reset and retry the nearest active error boundary (if one is active).
145
+ */
146
+ resetBoundary: () => void;
147
+ /**
148
+ * Trigger the nearest error boundary to display the error provided.
149
+ *
150
+ * ℹ️ React only handles errors thrown during render or during component lifecycle methods (e.g. effects and did-mount/did-update).
151
+ * Errors thrown in event handlers, or after async code has run, will not be caught.
152
+ * This method is a way to imperatively trigger an error boundary during these phases.
153
+ */
154
+ showBoundary: (error: Error) => void;
155
+ };
156
+
157
+ export declare type UseErrorBoundaryApi = {
158
+ error: Error | null;
159
+ resetBoundary: () => void;
160
+ showBoundary: (error: Error) => void;
161
+ };
162
+
163
+ export declare function withErrorBoundary<Type extends ComponentClass<unknown>, Props extends object>(Component: ComponentType<Props>, errorBoundaryProps: ErrorBoundaryProps): ForwardRefExoticComponent<PropsWithoutRef<Props> & RefAttributes<InstanceType<Type>>>;
164
+
165
+ export { }
@@ -1,151 +1,111 @@
1
- 'use client';
2
- import { createContext, Component, createElement, useContext, useState, useMemo, forwardRef } from 'react';
3
-
4
- const ErrorBoundaryContext = createContext(null);
5
-
6
- const initialState = {
7
- didCatch: false,
1
+ "use client";
2
+ import { createContext as l, Component as y, createElement as d, useContext as f, useState as p, useMemo as E, forwardRef as B } from "react";
3
+ const h = l(null), c = {
4
+ didCatch: !1,
8
5
  error: null
9
6
  };
10
- class ErrorBoundary extends Component {
11
- constructor(props) {
12
- super(props);
13
- this.resetErrorBoundary = this.resetErrorBoundary.bind(this);
14
- this.state = initialState;
7
+ class m extends y {
8
+ constructor(t) {
9
+ super(t), this.resetErrorBoundary = this.resetErrorBoundary.bind(this), this.state = c;
15
10
  }
16
- static getDerivedStateFromError(error) {
17
- return {
18
- didCatch: true,
19
- error
20
- };
11
+ static getDerivedStateFromError(t) {
12
+ return { didCatch: !0, error: t };
21
13
  }
22
- resetErrorBoundary() {
23
- const {
24
- error
25
- } = this.state;
26
- if (error !== null) {
27
- var _this$props$onReset, _this$props;
28
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
29
- args[_key] = arguments[_key];
30
- }
31
- (_this$props$onReset = (_this$props = this.props).onReset) === null || _this$props$onReset === void 0 ? void 0 : _this$props$onReset.call(_this$props, {
32
- args,
33
- reason: "imperative-api"
34
- });
35
- this.setState(initialState);
36
- }
14
+ resetErrorBoundary(...t) {
15
+ const { error: e } = this.state;
16
+ e !== null && (this.props.onReset?.({
17
+ args: t,
18
+ reason: "imperative-api"
19
+ }), this.setState(c));
37
20
  }
38
- componentDidCatch(error, info) {
39
- var _this$props$onError, _this$props2;
40
- (_this$props$onError = (_this$props2 = this.props).onError) === null || _this$props$onError === void 0 ? void 0 : _this$props$onError.call(_this$props2, error, info);
21
+ componentDidCatch(t, e) {
22
+ this.props.onError?.(t, e);
41
23
  }
42
- componentDidUpdate(prevProps, prevState) {
43
- const {
44
- didCatch
45
- } = this.state;
46
- const {
47
- resetKeys
48
- } = this.props;
49
-
50
- // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,
51
- // we'd end up resetting the error boundary immediately.
52
- // This would likely trigger a second error to be thrown.
53
- // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.
54
-
55
- if (didCatch && prevState.error !== null && hasArrayChanged(prevProps.resetKeys, resetKeys)) {
56
- var _this$props$onReset2, _this$props3;
57
- (_this$props$onReset2 = (_this$props3 = this.props).onReset) === null || _this$props$onReset2 === void 0 ? void 0 : _this$props$onReset2.call(_this$props3, {
58
- next: resetKeys,
59
- prev: prevProps.resetKeys,
60
- reason: "keys"
61
- });
62
- this.setState(initialState);
63
- }
24
+ componentDidUpdate(t, e) {
25
+ const { didCatch: o } = this.state, { resetKeys: n } = this.props;
26
+ o && e.error !== null && C(t.resetKeys, n) && (this.props.onReset?.({
27
+ next: n,
28
+ prev: t.resetKeys,
29
+ reason: "keys"
30
+ }), this.setState(c));
64
31
  }
65
32
  render() {
66
- const {
67
- children,
68
- fallbackRender,
69
- FallbackComponent,
70
- fallback
71
- } = this.props;
72
- const {
73
- didCatch,
74
- error
75
- } = this.state;
76
- let childToRender = children;
77
- if (didCatch) {
78
- const props = {
79
- error,
33
+ const { children: t, fallbackRender: e, FallbackComponent: o, fallback: n } = this.props, { didCatch: s, error: a } = this.state;
34
+ let i = t;
35
+ if (s) {
36
+ const u = {
37
+ error: a,
80
38
  resetErrorBoundary: this.resetErrorBoundary
81
39
  };
82
- if (typeof fallbackRender === "function") {
83
- childToRender = fallbackRender(props);
84
- } else if (FallbackComponent) {
85
- childToRender = createElement(FallbackComponent, props);
86
- } else if (fallback !== undefined) {
87
- childToRender = fallback;
88
- } else {
89
- throw error;
90
- }
40
+ if (typeof e == "function")
41
+ i = e(u);
42
+ else if (o)
43
+ i = d(o, u);
44
+ else if (n !== void 0)
45
+ i = n;
46
+ else
47
+ throw a;
91
48
  }
92
- return createElement(ErrorBoundaryContext.Provider, {
93
- value: {
94
- didCatch,
95
- error,
96
- resetErrorBoundary: this.resetErrorBoundary
97
- }
98
- }, childToRender);
49
+ return d(
50
+ h.Provider,
51
+ {
52
+ value: {
53
+ didCatch: s,
54
+ error: a,
55
+ resetErrorBoundary: this.resetErrorBoundary
56
+ }
57
+ },
58
+ i
59
+ );
99
60
  }
100
61
  }
101
- function hasArrayChanged() {
102
- let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
103
- let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
104
- return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
62
+ function C(r = [], t = []) {
63
+ return r.length !== t.length || r.some((e, o) => !Object.is(e, t[o]));
64
+ }
65
+ function x(r) {
66
+ return r !== null && typeof r == "object" && "didCatch" in r && typeof r.didCatch == "boolean" && "error" in r && "resetErrorBoundary" in r && typeof r.resetErrorBoundary == "function";
105
67
  }
106
-
107
- function assertErrorBoundaryContext(value) {
108
- if (value == null || typeof value.didCatch !== "boolean" || typeof value.resetErrorBoundary !== "function") {
68
+ function w(r) {
69
+ if (!x(r))
109
70
  throw new Error("ErrorBoundaryContext not found");
110
- }
111
71
  }
112
-
113
- function useErrorBoundary() {
114
- const context = useContext(ErrorBoundaryContext);
115
- assertErrorBoundaryContext(context);
116
- const [state, setState] = useState({
72
+ function S() {
73
+ const r = f(h);
74
+ w(r);
75
+ const { error: t, resetErrorBoundary: e } = r, [o, n] = p({
117
76
  error: null,
118
- hasError: false
119
- });
120
- const memoized = useMemo(() => ({
121
- resetBoundary: () => {
122
- context.resetErrorBoundary();
123
- setState({
124
- error: null,
125
- hasError: false
126
- });
127
- },
128
- showBoundary: error => setState({
129
- error,
130
- hasError: true
131
- })
132
- }), [context.resetErrorBoundary]);
133
- if (state.hasError) {
134
- throw state.error;
135
- }
136
- return memoized;
77
+ hasError: !1
78
+ }), s = E(
79
+ () => ({
80
+ error: t,
81
+ resetBoundary: () => {
82
+ e(), n({ error: null, hasError: !1 });
83
+ },
84
+ showBoundary: (a) => n({
85
+ error: a,
86
+ hasError: !0
87
+ })
88
+ }),
89
+ [t, e]
90
+ );
91
+ if (o.hasError)
92
+ throw o.error;
93
+ return s;
137
94
  }
138
-
139
- function withErrorBoundary(component, errorBoundaryProps) {
140
- const Wrapped = forwardRef((props, ref) => createElement(ErrorBoundary, errorBoundaryProps, createElement(component, {
141
- ...props,
142
- ref
143
- })));
144
-
145
- // Format for display in DevTools
146
- const name = component.displayName || component.name || "Unknown";
147
- Wrapped.displayName = "withErrorBoundary(".concat(name, ")");
148
- return Wrapped;
95
+ function k(r, t) {
96
+ const e = B(
97
+ (n, s) => d(
98
+ m,
99
+ t,
100
+ d(r, { ...n, ref: s })
101
+ )
102
+ ), o = r.displayName || r.name || "Unknown";
103
+ return e.displayName = `withErrorBoundary(${o})`, e;
149
104
  }
150
-
151
- export { ErrorBoundary, ErrorBoundaryContext, useErrorBoundary, withErrorBoundary };
105
+ export {
106
+ m as ErrorBoundary,
107
+ h as ErrorBoundaryContext,
108
+ S as useErrorBoundary,
109
+ k as withErrorBoundary
110
+ };
111
+ //# sourceMappingURL=react-error-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-error-boundary.js","sources":["../lib/context/ErrorBoundaryContext.ts","../lib/components/ErrorBoundary.tsx","../lib/utils/isErrorBoundaryContext.ts","../lib/utils/assertErrorBoundaryContext.ts","../lib/hooks/useErrorBoundary.ts","../lib/utils/withErrorBoundary.ts"],"sourcesContent":["import { createContext } from \"react\";\n\nexport type ErrorBoundaryContextType = {\n didCatch: boolean;\n error: Error | null;\n resetErrorBoundary: (...args: unknown[]) => void;\n};\n\nexport const ErrorBoundaryContext =\n createContext<ErrorBoundaryContextType | null>(null);\n","import { Component, createElement, type ErrorInfo } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport type { ErrorBoundaryProps, FallbackProps } from \"../types\";\n\nconst isDevelopment = import.meta.env.DEV;\n\ntype ErrorBoundaryState =\n | {\n didCatch: true;\n error: Error;\n }\n | {\n didCatch: false;\n error: null;\n };\n\nconst initialState: ErrorBoundaryState = {\n didCatch: false,\n error: null,\n};\n\n/**\n * A reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.\n * Wrap this component around other React components to \"catch\" errors and render a fallback UI.\n *\n * This package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),\n * so it has all of the advantages and constraints of that API.\n * This means that it can't catch errors during:\n * - Server side rendering</li>\n * - Event handlers\n * - Asynchronous code (including effects)\n *\n * ℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.\n * Refer to the documentation to determine which is best for your application.\n *\n * ℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `\"use client\";` directive.\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.resetErrorBoundary = this.resetErrorBoundary.bind(this);\n this.state = initialState;\n }\n\n static getDerivedStateFromError(error: Error) {\n return { didCatch: true, error };\n }\n\n resetErrorBoundary(...args: unknown[]) {\n const { error } = this.state;\n\n if (error !== null) {\n this.props.onReset?.({\n args,\n reason: \"imperative-api\",\n });\n\n this.setState(initialState);\n }\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n this.props.onError?.(error, info);\n }\n\n componentDidUpdate(\n prevProps: ErrorBoundaryProps,\n prevState: ErrorBoundaryState,\n ) {\n const { didCatch } = this.state;\n const { resetKeys } = this.props;\n\n // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,\n // we'd end up resetting the error boundary immediately.\n // This would likely trigger a second error to be thrown.\n // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.\n\n if (\n didCatch &&\n prevState.error !== null &&\n hasArrayChanged(prevProps.resetKeys, resetKeys)\n ) {\n this.props.onReset?.({\n next: resetKeys,\n prev: prevProps.resetKeys,\n reason: \"keys\",\n });\n\n this.setState(initialState);\n }\n }\n\n render() {\n const { children, fallbackRender, FallbackComponent, fallback } =\n this.props;\n const { didCatch, error } = this.state;\n\n let childToRender = children;\n\n if (didCatch) {\n const props: FallbackProps = {\n error,\n resetErrorBoundary: this.resetErrorBoundary,\n };\n\n if (typeof fallbackRender === \"function\") {\n childToRender = fallbackRender(props);\n } else if (FallbackComponent) {\n childToRender = createElement(FallbackComponent, props);\n } else if (fallback !== undefined) {\n childToRender = fallback;\n } else {\n if (isDevelopment) {\n console.error(\n \"react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop\",\n );\n }\n\n throw error;\n }\n }\n\n return createElement(\n ErrorBoundaryContext.Provider,\n {\n value: {\n didCatch,\n error,\n resetErrorBoundary: this.resetErrorBoundary,\n },\n },\n childToRender,\n );\n }\n}\n\nfunction hasArrayChanged(a: unknown[] = [], b: unknown[] = []) {\n return (\n a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]))\n );\n}\n","import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\n\nexport function isErrorBoundaryContext(\n value: unknown,\n): value is ErrorBoundaryContextType {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"didCatch\" in value &&\n typeof value.didCatch === \"boolean\" &&\n \"error\" in value &&\n \"resetErrorBoundary\" in value &&\n typeof value.resetErrorBoundary === \"function\"\n );\n}\n","import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\nimport { isErrorBoundaryContext } from \"./isErrorBoundaryContext\";\n\nexport function assertErrorBoundaryContext(\n value: unknown,\n): asserts value is ErrorBoundaryContextType {\n if (!isErrorBoundaryContext(value)) {\n throw new Error(\"ErrorBoundaryContext not found\");\n }\n}\n","import { useContext, useMemo, useState } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport { assertErrorBoundaryContext } from \"../utils/assertErrorBoundaryContext\";\n\ntype UseErrorBoundaryState =\n | { error: Error; hasError: true }\n | { error: null; hasError: false };\n\nexport type UseErrorBoundaryApi = {\n error: Error | null;\n resetBoundary: () => void;\n showBoundary: (error: Error) => void;\n};\n\n/**\n * Convenience hook for imperatively showing or dismissing error boundaries.\n *\n * ⚠️ This hook must only be used within an `ErrorBoundary` subtree.\n */\nexport function useErrorBoundary(): {\n /**\n * The currently visible `Error` (if one has been thrown).\n */\n error: Error | null;\n\n /**\n * Method to reset and retry the nearest active error boundary (if one is active).\n */\n resetBoundary: () => void;\n\n /**\n * Trigger the nearest error boundary to display the error provided.\n *\n * ℹ️ React only handles errors thrown during render or during component lifecycle methods (e.g. effects and did-mount/did-update).\n * Errors thrown in event handlers, or after async code has run, will not be caught.\n * This method is a way to imperatively trigger an error boundary during these phases.\n */\n showBoundary: (error: Error) => void;\n} {\n const context = useContext(ErrorBoundaryContext);\n\n assertErrorBoundaryContext(context);\n\n const { error, resetErrorBoundary } = context;\n\n const [state, setState] = useState<UseErrorBoundaryState>({\n error: null,\n hasError: false,\n });\n\n const memoized = useMemo(\n () => ({\n error,\n resetBoundary: () => {\n resetErrorBoundary();\n setState({ error: null, hasError: false });\n },\n showBoundary: (error: Error) =>\n setState({\n error,\n hasError: true,\n }),\n }),\n [error, resetErrorBoundary],\n );\n\n if (state.hasError) {\n throw state.error;\n }\n\n return memoized;\n}\n","import {\n createElement,\n forwardRef,\n type ComponentClass,\n type ComponentType,\n} from \"react\";\nimport { ErrorBoundary } from \"../components/ErrorBoundary\";\nimport type { ErrorBoundaryProps } from \"../types\";\n\nexport function withErrorBoundary<\n Type extends ComponentClass<unknown>,\n Props extends object,\n>(Component: ComponentType<Props>, errorBoundaryProps: ErrorBoundaryProps) {\n const Wrapped = forwardRef<InstanceType<Type>, Props>((props, ref) =>\n createElement(\n ErrorBoundary,\n errorBoundaryProps,\n createElement(Component, { ...props, ref } as Props),\n ),\n );\n\n // Format for display in DevTools\n const name = Component.displayName || Component.name || \"Unknown\";\n Wrapped.displayName = `withErrorBoundary(${name})`;\n\n return Wrapped;\n}\n"],"names":["ErrorBoundaryContext","createContext","initialState","ErrorBoundary","Component","props","error","args","info","prevProps","prevState","didCatch","resetKeys","hasArrayChanged","children","fallbackRender","FallbackComponent","fallback","childToRender","createElement","a","b","item","index","isErrorBoundaryContext","value","assertErrorBoundaryContext","useErrorBoundary","context","useContext","resetErrorBoundary","state","setState","useState","memoized","useMemo","withErrorBoundary","errorBoundaryProps","Wrapped","forwardRef","ref","name"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-error-boundary",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "type": "module",
5
5
  "description": "Simple reusable React error boundary component",
6
6
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
@@ -9,73 +9,117 @@
9
9
  "type": "git",
10
10
  "url": "https://github.com/bvaughn/react-error-boundary"
11
11
  },
12
- "exports": {
13
- ".": {
14
- "types": "./dist/react-error-boundary.js",
15
- "development": "./dist/react-error-boundary.development.js",
16
- "default": "./dist/react-error-boundary.js"
17
- },
18
- "./package.json": "./package.json"
19
- },
20
- "imports": {
21
- "#is-development": {
22
- "development": "./src/env-conditions/development.ts",
23
- "default": "./src/env-conditions/production.ts"
24
- }
25
- },
12
+ "contributors": [
13
+ "Brian Vaughn <brian.david.vaughn@gmail.com> (https://github.com/bvaughn/)"
14
+ ],
15
+ "homepage": "https://react-error-boundary-lib.vercel.app/",
16
+ "keywords": [
17
+ "react",
18
+ "reactjs",
19
+ "virtual",
20
+ "window",
21
+ "windowed",
22
+ "list",
23
+ "scrolling",
24
+ "infinite",
25
+ "virtualized",
26
+ "table",
27
+ "grid",
28
+ "spreadsheet"
29
+ ],
30
+ "main": "dist/react-error-boundary.cjs",
31
+ "module": "dist/react-error-boundary.js",
26
32
  "types": "dist/react-error-boundary.d.ts",
27
33
  "files": [
28
34
  "dist"
29
35
  ],
30
- "sideEffects": false,
31
- "dependencies": {
32
- "@babel/runtime": "^7.12.5"
36
+ "scripts": {
37
+ "dev": "vite",
38
+ "dev:integrations": "pnpm -C integrations/vite/ run dev",
39
+ "build": "pnpm run build:lib && pnpm run build:docs",
40
+ "build:docs": "TARGET=docs vite build",
41
+ "build:lib": "TARGET=lib vite build",
42
+ "compile": "pnpm run compile:docs && pnpm run compile:examples",
43
+ "compile:docs": "tsx ./scripts/compile-docs",
44
+ "compile:examples": "tsx ./scripts/compile-examples",
45
+ "compress:og-image": "tsx ./scripts/compress-og-image",
46
+ "lint": "eslint .",
47
+ "prerelease": "rm -rf dist && pnpm run build:lib",
48
+ "prettier": "prettier --write \"**/*.{css,html,js,json,jsx,ts,tsx}\"",
49
+ "prettier:ci": "prettier --check \"**/*.{css,html,js,json,jsx,ts,tsx}\"",
50
+ "preview": "vite preview",
51
+ "test": "vitest",
52
+ "test:ci": "vitest run",
53
+ "test:debug": "vitest --inspect-brk=127.0.0.1:3000 --no-file-parallelism",
54
+ "tsc": "tsc -b"
33
55
  },
34
- "devDependencies": {
35
- "@babel/preset-env": "^7.22.5",
36
- "@babel/preset-typescript": "^7.21.5",
37
- "@preconstruct/cli": "^2.8.12",
38
- "@types/assert": "^1.5.10",
39
- "@types/react": "^18.3.17",
40
- "@types/react-dom": "^18",
41
- "assert": "^2.0.0",
42
- "eslint": "^9.13.0",
43
- "eslint-config-prettier": "^9.1.0",
44
- "eslint-plugin-import": "^2.25.2",
45
- "eslint-plugin-prettier": "^5.2.1",
46
- "eslint-plugin-react": "^7.37.2",
47
- "globals": "^15.11.0",
48
- "prettier": "^3.0.1",
49
- "react": "^18",
50
- "react-dom": "^18",
51
- "rimraf": "^6.0.1",
52
- "vitest": "^3.1.2",
53
- "typescript": "^5.8.3",
54
- "typescript-eslint": "^8.18.0"
56
+ "lint-staged": {
57
+ "**/*": "prettier --write --ignore-unknown"
55
58
  },
56
59
  "peerDependencies": {
57
- "react": ">=16.13.1"
58
- },
59
- "preconstruct": {
60
- "exports": {
61
- "importConditionDefaultExport": "default"
62
- },
63
- "___experimentalFlags_WILL_CHANGE_IN_PATCH": {
64
- "distInRoot": true,
65
- "importsConditions": true,
66
- "typeModule": true
67
- }
60
+ "react": "^18.0.0 || ^19.0.0",
61
+ "react-dom": "^18.0.0 || ^19.0.0"
68
62
  },
69
- "scripts": {
70
- "clear": "pnpm clear:builds & pnpm clear:node_modules",
71
- "clear:builds": "rimraf ./dist",
72
- "clear:node_modules": "rimraf ./node_modules",
73
- "prerelease": "preconstruct build",
74
- "lint": "eslint .",
75
- "lint:fix": "eslint . --fix",
76
- "test": "vitest --environment=jsdom --watch=false",
77
- "test:watch": "vitest --environment=jsdom --watch",
78
- "typescript": "tsc --noEmit",
79
- "typescript:watch": "tsc --noEmit --watch"
63
+ "devDependencies": {
64
+ "@csstools/postcss-oklab-function": "^4.0.11",
65
+ "@eslint/js": "^9.30.1",
66
+ "@headlessui/react": "^2.2.4",
67
+ "@headlessui/tailwindcss": "^0.2.2",
68
+ "@heroicons/react": "^2.2.0",
69
+ "@tailwindcss/vite": "^4.1.11",
70
+ "@tailwindplus/elements": "^1.0.5",
71
+ "@testing-library/jest-dom": "^6.6.4",
72
+ "@testing-library/react": "^16.3.0",
73
+ "@testing-library/user-event": "^14.6.1",
74
+ "@types/bytes": "^3.1.5",
75
+ "@types/compression": "^1.8.1",
76
+ "@types/markdown-it": "^14.1.2",
77
+ "@types/node": "^24.2.0",
78
+ "@types/react": "^19.1.8",
79
+ "@types/react-dom": "^19.2.3",
80
+ "@types/sharp": "^0.32.0",
81
+ "@vitejs/plugin-react-swc": "^3.10.2",
82
+ "bytes": "^3.1.2",
83
+ "clsx": "^2.1.1",
84
+ "compression": "^1.8.1",
85
+ "csstype": "^3.1.3",
86
+ "eslint": "^9.30.1",
87
+ "eslint-plugin-react-hooks": "^5.2.0",
88
+ "eslint-plugin-react-refresh": "^0.4.20",
89
+ "globals": "^16.3.0",
90
+ "husky": "^9.1.7",
91
+ "jsdom": "^26.1.0",
92
+ "lint-staged": "^16.1.4",
93
+ "markdown-it": "^14.1.0",
94
+ "marked": "^16.4.1",
95
+ "postcss": "^8.5.6",
96
+ "prettier": "3.6.2",
97
+ "prettier-plugin-tailwindcss": "^0.7.1",
98
+ "react": "^19.2.3",
99
+ "react-docgen-typescript": "^2.4.0",
100
+ "react-dom": "^19.2.3",
101
+ "react-error-boundary": "^6.0.0",
102
+ "react-lib-tools": "^0.0.30",
103
+ "react-router-dom": "^7.6.3",
104
+ "rollup-plugin-terser": "^7.0.2",
105
+ "rollup-plugin-visualizer": "^6.0.3",
106
+ "rollup-preserve-directives": "^1.1.3",
107
+ "sharp": "^0.34.5",
108
+ "sirv": "^3.0.2",
109
+ "tailwind-merge": "^3.3.1",
110
+ "tailwindcss": "^4.1.11",
111
+ "terser": "^5.43.1",
112
+ "ts-blank-space": "^0.6.2",
113
+ "ts-node": "^10.9.2",
114
+ "tsx": "^4.21.0",
115
+ "typescript": "~5.8.3",
116
+ "typescript-eslint": "^8.35.1",
117
+ "typescript-json-schema": "^0.65.1",
118
+ "vite": "^7.0.4",
119
+ "vite-plugin-dts": "^4.5.4",
120
+ "vite-plugin-svgr": "^4.3.0",
121
+ "vitest": "^3.2.4",
122
+ "vitest-fail-on-console": "^0.10.1",
123
+ "zustand": "^5.0.7"
80
124
  }
81
- }
125
+ }
@@ -1,21 +0,0 @@
1
- import { Component, ErrorInfo } from "react";
2
- import { ErrorBoundaryProps } from "./types.js";
3
- type ErrorBoundaryState = {
4
- didCatch: true;
5
- error: any;
6
- } | {
7
- didCatch: false;
8
- error: null;
9
- };
10
- export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
11
- constructor(props: ErrorBoundaryProps);
12
- static getDerivedStateFromError(error: Error): {
13
- didCatch: boolean;
14
- error: Error;
15
- };
16
- resetErrorBoundary(...args: any[]): void;
17
- componentDidCatch(error: Error, info: ErrorInfo): void;
18
- componentDidUpdate(prevProps: ErrorBoundaryProps, prevState: ErrorBoundaryState): void;
19
- render(): import("react").FunctionComponentElement<import("react").ProviderProps<import("./ErrorBoundaryContext.js").ErrorBoundaryContextType | null>>;
20
- }
21
- export {};
@@ -1,6 +0,0 @@
1
- export type ErrorBoundaryContextType = {
2
- didCatch: boolean;
3
- error: any;
4
- resetErrorBoundary: (...args: any[]) => void;
5
- };
6
- export declare const ErrorBoundaryContext: import("react").Context<ErrorBoundaryContextType | null>;
@@ -1,5 +0,0 @@
1
- export * from "./ErrorBoundary.js";
2
- export * from "./ErrorBoundaryContext.js";
3
- export * from "./useErrorBoundary.js";
4
- export * from "./withErrorBoundary.js";
5
- export * from "./types.js";
@@ -1,34 +0,0 @@
1
- import { ComponentType, ErrorInfo, PropsWithChildren, ReactNode } from "react";
2
- export type FallbackProps = {
3
- error: any;
4
- resetErrorBoundary: (...args: any[]) => void;
5
- };
6
- type ErrorBoundarySharedProps = PropsWithChildren<{
7
- onError?: (error: Error, info: ErrorInfo) => void;
8
- onReset?: (details: {
9
- reason: "imperative-api";
10
- args: any[];
11
- } | {
12
- reason: "keys";
13
- prev: any[] | undefined;
14
- next: any[] | undefined;
15
- }) => void;
16
- resetKeys?: any[];
17
- }>;
18
- export type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
19
- fallback?: never;
20
- FallbackComponent: ComponentType<FallbackProps>;
21
- fallbackRender?: never;
22
- };
23
- export type ErrorBoundaryPropsWithRender = ErrorBoundarySharedProps & {
24
- fallback?: never;
25
- FallbackComponent?: never;
26
- fallbackRender: (props: FallbackProps) => ReactNode;
27
- };
28
- export type ErrorBoundaryPropsWithFallback = ErrorBoundarySharedProps & {
29
- fallback: ReactNode;
30
- FallbackComponent?: never;
31
- fallbackRender?: never;
32
- };
33
- export type ErrorBoundaryProps = ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender;
34
- export {};
@@ -1,5 +0,0 @@
1
- export type UseErrorBoundaryApi<TError> = {
2
- resetBoundary: () => void;
3
- showBoundary: (error: TError) => void;
4
- };
5
- export declare function useErrorBoundary<TError = any>(): UseErrorBoundaryApi<TError>;
@@ -1,3 +0,0 @@
1
- import { RefAttributes, ForwardRefExoticComponent, PropsWithoutRef, ComponentType, ComponentRef, ComponentProps } from "react";
2
- import { ErrorBoundaryProps } from "./types.js";
3
- export declare function withErrorBoundary<T extends ComponentType<any>>(component: T, errorBoundaryProps: ErrorBoundaryProps): ForwardRefExoticComponent<PropsWithoutRef<ComponentProps<T>> & RefAttributes<ComponentRef<T>>>;
@@ -1,154 +0,0 @@
1
- 'use client';
2
- import { createContext, Component, createElement, useContext, useState, useMemo, forwardRef } from 'react';
3
-
4
- const ErrorBoundaryContext = createContext(null);
5
-
6
- const initialState = {
7
- didCatch: false,
8
- error: null
9
- };
10
- class ErrorBoundary extends Component {
11
- constructor(props) {
12
- super(props);
13
- this.resetErrorBoundary = this.resetErrorBoundary.bind(this);
14
- this.state = initialState;
15
- }
16
- static getDerivedStateFromError(error) {
17
- return {
18
- didCatch: true,
19
- error
20
- };
21
- }
22
- resetErrorBoundary() {
23
- const {
24
- error
25
- } = this.state;
26
- if (error !== null) {
27
- var _this$props$onReset, _this$props;
28
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
29
- args[_key] = arguments[_key];
30
- }
31
- (_this$props$onReset = (_this$props = this.props).onReset) === null || _this$props$onReset === void 0 ? void 0 : _this$props$onReset.call(_this$props, {
32
- args,
33
- reason: "imperative-api"
34
- });
35
- this.setState(initialState);
36
- }
37
- }
38
- componentDidCatch(error, info) {
39
- var _this$props$onError, _this$props2;
40
- (_this$props$onError = (_this$props2 = this.props).onError) === null || _this$props$onError === void 0 ? void 0 : _this$props$onError.call(_this$props2, error, info);
41
- }
42
- componentDidUpdate(prevProps, prevState) {
43
- const {
44
- didCatch
45
- } = this.state;
46
- const {
47
- resetKeys
48
- } = this.props;
49
-
50
- // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,
51
- // we'd end up resetting the error boundary immediately.
52
- // This would likely trigger a second error to be thrown.
53
- // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.
54
-
55
- if (didCatch && prevState.error !== null && hasArrayChanged(prevProps.resetKeys, resetKeys)) {
56
- var _this$props$onReset2, _this$props3;
57
- (_this$props$onReset2 = (_this$props3 = this.props).onReset) === null || _this$props$onReset2 === void 0 ? void 0 : _this$props$onReset2.call(_this$props3, {
58
- next: resetKeys,
59
- prev: prevProps.resetKeys,
60
- reason: "keys"
61
- });
62
- this.setState(initialState);
63
- }
64
- }
65
- render() {
66
- const {
67
- children,
68
- fallbackRender,
69
- FallbackComponent,
70
- fallback
71
- } = this.props;
72
- const {
73
- didCatch,
74
- error
75
- } = this.state;
76
- let childToRender = children;
77
- if (didCatch) {
78
- const props = {
79
- error,
80
- resetErrorBoundary: this.resetErrorBoundary
81
- };
82
- if (typeof fallbackRender === "function") {
83
- childToRender = fallbackRender(props);
84
- } else if (FallbackComponent) {
85
- childToRender = createElement(FallbackComponent, props);
86
- } else if (fallback !== undefined) {
87
- childToRender = fallback;
88
- } else {
89
- {
90
- console.error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop");
91
- }
92
- throw error;
93
- }
94
- }
95
- return createElement(ErrorBoundaryContext.Provider, {
96
- value: {
97
- didCatch,
98
- error,
99
- resetErrorBoundary: this.resetErrorBoundary
100
- }
101
- }, childToRender);
102
- }
103
- }
104
- function hasArrayChanged() {
105
- let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
106
- let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
107
- return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
108
- }
109
-
110
- function assertErrorBoundaryContext(value) {
111
- if (value == null || typeof value.didCatch !== "boolean" || typeof value.resetErrorBoundary !== "function") {
112
- throw new Error("ErrorBoundaryContext not found");
113
- }
114
- }
115
-
116
- function useErrorBoundary() {
117
- const context = useContext(ErrorBoundaryContext);
118
- assertErrorBoundaryContext(context);
119
- const [state, setState] = useState({
120
- error: null,
121
- hasError: false
122
- });
123
- const memoized = useMemo(() => ({
124
- resetBoundary: () => {
125
- context.resetErrorBoundary();
126
- setState({
127
- error: null,
128
- hasError: false
129
- });
130
- },
131
- showBoundary: error => setState({
132
- error,
133
- hasError: true
134
- })
135
- }), [context.resetErrorBoundary]);
136
- if (state.hasError) {
137
- throw state.error;
138
- }
139
- return memoized;
140
- }
141
-
142
- function withErrorBoundary(component, errorBoundaryProps) {
143
- const Wrapped = forwardRef((props, ref) => createElement(ErrorBoundary, errorBoundaryProps, createElement(component, {
144
- ...props,
145
- ref
146
- })));
147
-
148
- // Format for display in DevTools
149
- const name = component.displayName || component.name || "Unknown";
150
- Wrapped.displayName = "withErrorBoundary(".concat(name, ")");
151
- return Wrapped;
152
- }
153
-
154
- export { ErrorBoundary, ErrorBoundaryContext, useErrorBoundary, withErrorBoundary };