@swan-io/lake 2.2.1 → 2.3.0
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/package.json
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Component, ErrorInfo, ReactElement, ReactNode } from "react";
|
|
2
|
+
type Props = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
fallback: (data: {
|
|
5
|
+
error: Error;
|
|
6
|
+
resetError: () => void;
|
|
7
|
+
}) => ReactElement;
|
|
8
|
+
onError?: (error: Error, componentStack: ErrorInfo["componentStack"]) => void;
|
|
9
|
+
};
|
|
10
|
+
type State = {
|
|
11
|
+
error: Error | null;
|
|
12
|
+
};
|
|
13
|
+
export declare class ErrorBoundary extends Component<Props, State> {
|
|
14
|
+
state: State;
|
|
15
|
+
static getDerivedStateFromError(error: Error): State;
|
|
16
|
+
componentDidCatch(error: Error, { componentStack }: ErrorInfo): void;
|
|
17
|
+
resetError: () => void;
|
|
18
|
+
render(): ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
|
|
2
|
+
// https://github.com/getsentry/sentry-javascript/blob/7.56.0/packages/react/src/errorboundary.tsx
|
|
3
|
+
import { Component, isValidElement } from "react";
|
|
4
|
+
const isError = (value) => {
|
|
5
|
+
const string = Object.prototype.toString.call(value);
|
|
6
|
+
if (string === "[object Error]" ||
|
|
7
|
+
string === "[object Exception]" ||
|
|
8
|
+
string === "[object DOMException]") {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
return value instanceof Error;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const setCause = (error, cause) => {
|
|
19
|
+
const seen = new WeakMap();
|
|
20
|
+
const recurse = (error, cause) => {
|
|
21
|
+
if (seen.has(error)) {
|
|
22
|
+
return; // Prevent a stack overflow caused by a possible recursive loop
|
|
23
|
+
}
|
|
24
|
+
if (error.cause != null) {
|
|
25
|
+
seen.set(error, true);
|
|
26
|
+
return recurse(error.cause, cause);
|
|
27
|
+
}
|
|
28
|
+
error.cause = cause;
|
|
29
|
+
};
|
|
30
|
+
recurse(error, cause);
|
|
31
|
+
};
|
|
32
|
+
const initialState = {
|
|
33
|
+
error: null,
|
|
34
|
+
};
|
|
35
|
+
export class ErrorBoundary extends Component {
|
|
36
|
+
state = initialState;
|
|
37
|
+
static getDerivedStateFromError(error) {
|
|
38
|
+
return { error };
|
|
39
|
+
}
|
|
40
|
+
componentDidCatch(error, { componentStack }) {
|
|
41
|
+
const { onError } = this.props;
|
|
42
|
+
if (isError(error)) {
|
|
43
|
+
const cause = new Error(error.message);
|
|
44
|
+
cause.name = `ErrorBoundary ${cause.name}`;
|
|
45
|
+
cause.stack = componentStack;
|
|
46
|
+
setCause(error, cause);
|
|
47
|
+
}
|
|
48
|
+
if (onError != null) {
|
|
49
|
+
onError(error, componentStack);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
resetError = () => {
|
|
53
|
+
const { error } = this.state;
|
|
54
|
+
if (error !== null) {
|
|
55
|
+
this.setState(initialState);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
render() {
|
|
59
|
+
const { children, fallback } = this.props;
|
|
60
|
+
const { error } = this.state;
|
|
61
|
+
if (error === null) {
|
|
62
|
+
return children;
|
|
63
|
+
}
|
|
64
|
+
const element = fallback({ error, resetError: this.resetError });
|
|
65
|
+
return isValidElement(element) ? element : null;
|
|
66
|
+
}
|
|
67
|
+
}
|