@sentry/react 8.5.0 → 8.6.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/README.md +31 -4
- package/cjs/error.js +112 -0
- package/cjs/error.js.map +1 -0
- package/cjs/errorboundary.js +10 -56
- package/cjs/errorboundary.js.map +1 -1
- package/cjs/index.js +2 -0
- package/cjs/index.js.map +1 -1
- package/esm/error.js +107 -0
- package/esm/error.js.map +1 -0
- package/esm/errorboundary.js +12 -57
- package/esm/errorboundary.js.map +1 -1
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/package.json +7 -7
- package/types/error.d.ts +41 -0
- package/types/error.d.ts.map +1 -0
- package/types/errorboundary.d.ts +4 -5
- package/types/errorboundary.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types-ts3.8/error.d.ts +41 -0
- package/types-ts3.8/errorboundary.d.ts +4 -5
- package/types-ts3.8/index.d.ts +1 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ To use this SDK, call `Sentry.init(options)` before you mount your React compone
|
|
|
20
20
|
|
|
21
21
|
```javascript
|
|
22
22
|
import React from 'react';
|
|
23
|
-
import
|
|
23
|
+
import { createRoot } from 'react-dom/client';
|
|
24
24
|
import * as Sentry from '@sentry/react';
|
|
25
25
|
|
|
26
26
|
Sentry.init({
|
|
@@ -30,12 +30,39 @@ Sentry.init({
|
|
|
30
30
|
|
|
31
31
|
// ...
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const container = document.getElementById(“app”);
|
|
34
|
+
const root = createRoot(container);
|
|
35
|
+
root.render(<App />);
|
|
34
36
|
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
+
// also works with hydrateRoot
|
|
38
|
+
// const domNode = document.getElementById('root');
|
|
39
|
+
// const root = hydrateRoot(domNode, reactNode);
|
|
40
|
+
// root.render(<App />);
|
|
37
41
|
```
|
|
38
42
|
|
|
43
|
+
### React 19
|
|
44
|
+
|
|
45
|
+
Starting with React 19, the `createRoot` and `hydrateRoot` methods expose error hooks that can be used to capture errors
|
|
46
|
+
automatically. Use the `Sentry.reactErrorHandler` function to capture errors in the error hooks you are interested in.
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
const container = document.getElementById(“app”);
|
|
50
|
+
const root = createRoot(container, {
|
|
51
|
+
// Callback called when an error is thrown and not caught by an Error Boundary.
|
|
52
|
+
onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
|
|
53
|
+
console.warn('Uncaught error', error, errorInfo.componentStack);
|
|
54
|
+
}),
|
|
55
|
+
// Callback called when React catches an error in an Error Boundary.
|
|
56
|
+
onCaughtError: Sentry.reactErrorHandler(),
|
|
57
|
+
// Callback called when React automatically recovers from errors.
|
|
58
|
+
onRecoverableError: Sentry.reactErrorHandler(),
|
|
59
|
+
});
|
|
60
|
+
root.render(<App />);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If you want more finely grained control over error handling, we recommend only adding the `onUncaughtError` and
|
|
64
|
+
`onRecoverableError` hooks and using an `ErrorBoundary` component instead of the `onCaughtError` hook.
|
|
65
|
+
|
|
39
66
|
### ErrorBoundary
|
|
40
67
|
|
|
41
68
|
`@sentry/react` exports an ErrorBoundary component that will automatically send Javascript errors from inside a
|
package/cjs/error.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
const browser = require('@sentry/browser');
|
|
4
|
+
const utils = require('@sentry/utils');
|
|
5
|
+
const React = require('react');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* See if React major version is 17+ by parsing version string.
|
|
9
|
+
*/
|
|
10
|
+
function isAtLeastReact17(reactVersion) {
|
|
11
|
+
const reactMajor = reactVersion.match(/^([^.]+)/);
|
|
12
|
+
return reactMajor !== null && parseInt(reactMajor[0]) >= 17;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Recurse through `error.cause` chain to set cause on an error.
|
|
17
|
+
*/
|
|
18
|
+
function setCause(error, cause) {
|
|
19
|
+
const seenErrors = new WeakSet();
|
|
20
|
+
|
|
21
|
+
function recurse(error, cause) {
|
|
22
|
+
// If we've already seen the error, there is a recursive loop somewhere in the error's
|
|
23
|
+
// cause chain. Let's just bail out then to prevent a stack overflow.
|
|
24
|
+
if (seenErrors.has(error)) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (error.cause) {
|
|
28
|
+
seenErrors.add(error);
|
|
29
|
+
return recurse(error.cause, cause);
|
|
30
|
+
}
|
|
31
|
+
error.cause = cause;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
recurse(error, cause);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Captures an error that was thrown by a React ErrorBoundary or React root.
|
|
39
|
+
*
|
|
40
|
+
* @param error The error to capture.
|
|
41
|
+
* @param errorInfo The errorInfo provided by React.
|
|
42
|
+
* @param hint Optional additional data to attach to the Sentry event.
|
|
43
|
+
* @returns the id of the captured Sentry event.
|
|
44
|
+
*/
|
|
45
|
+
function captureReactException(
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
error,
|
|
48
|
+
{ componentStack },
|
|
49
|
+
hint,
|
|
50
|
+
) {
|
|
51
|
+
// If on React version >= 17, create stack trace from componentStack param and links
|
|
52
|
+
// to to the original error using `error.cause` otherwise relies on error param for stacktrace.
|
|
53
|
+
// Linking errors requires the `LinkedErrors` integration be enabled.
|
|
54
|
+
// See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks
|
|
55
|
+
//
|
|
56
|
+
// Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked
|
|
57
|
+
// with non-error objects. This is why we need to check if the error is an error-like object.
|
|
58
|
+
// See: https://github.com/getsentry/sentry-javascript/issues/6167
|
|
59
|
+
if (isAtLeastReact17(React.version) && utils.isError(error) && componentStack) {
|
|
60
|
+
const errorBoundaryError = new Error(error.message);
|
|
61
|
+
errorBoundaryError.name = `React ErrorBoundary ${error.name}`;
|
|
62
|
+
errorBoundaryError.stack = componentStack;
|
|
63
|
+
|
|
64
|
+
// Using the `LinkedErrors` integration to link the errors together.
|
|
65
|
+
setCause(error, errorBoundaryError);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return browser.captureException(error, {
|
|
69
|
+
...hint,
|
|
70
|
+
captureContext: {
|
|
71
|
+
contexts: { react: { componentStack } },
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,
|
|
78
|
+
* and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.
|
|
79
|
+
*
|
|
80
|
+
* @param callback An optional callback that will be called after the error is captured.
|
|
81
|
+
* Use this to add custom handling for errors.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
*
|
|
85
|
+
* ```JavaScript
|
|
86
|
+
* const root = createRoot(container, {
|
|
87
|
+
* onCaughtError: Sentry.reactErrorHandler(),
|
|
88
|
+
* onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
|
|
89
|
+
* console.warn('Caught error', error, errorInfo.componentStack);
|
|
90
|
+
* });
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
function reactErrorHandler(
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
+
callback,
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
) {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
return (error, errorInfo) => {
|
|
101
|
+
const eventId = captureReactException(error, errorInfo);
|
|
102
|
+
if (callback) {
|
|
103
|
+
callback(error, errorInfo, eventId);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
exports.captureReactException = captureReactException;
|
|
109
|
+
exports.isAtLeastReact17 = isAtLeastReact17;
|
|
110
|
+
exports.reactErrorHandler = reactErrorHandler;
|
|
111
|
+
exports.setCause = setCause;
|
|
112
|
+
//# sourceMappingURL=error.js.map
|
package/cjs/error.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sources":["../../src/error.ts"],"sourcesContent":["import { captureException } from '@sentry/browser';\nimport type { EventHint } from '@sentry/types';\nimport { isError } from '@sentry/utils';\nimport { version } from 'react';\nimport type { ErrorInfo } from 'react';\n\n/**\n * See if React major version is 17+ by parsing version string.\n */\nexport function isAtLeastReact17(reactVersion: string): boolean {\n const reactMajor = reactVersion.match(/^([^.]+)/);\n return reactMajor !== null && parseInt(reactMajor[0]) >= 17;\n}\n\n/**\n * Recurse through `error.cause` chain to set cause on an error.\n */\nexport function setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakSet();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.add(error);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * Captures an error that was thrown by a React ErrorBoundary or React root.\n *\n * @param error The error to capture.\n * @param errorInfo The errorInfo provided by React.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nexport function captureReactException(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n { componentStack }: ErrorInfo,\n hint?: EventHint,\n): string {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(version) && isError(error) && componentStack) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n return captureException(error, {\n ...hint,\n captureContext: {\n contexts: { react: { componentStack } },\n },\n });\n}\n\n/**\n * Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,\n * and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.\n *\n * @param callback An optional callback that will be called after the error is captured.\n * Use this to add custom handling for errors.\n *\n * @example\n *\n * ```JavaScript\n * const root = createRoot(container, {\n * onCaughtError: Sentry.reactErrorHandler(),\n * onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {\n * console.warn('Caught error', error, errorInfo.componentStack);\n * });\n * });\n * ```\n */\nexport function reactErrorHandler(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback?: (error: any, errorInfo: ErrorInfo, eventId: string) => void,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): (error: any, errorInfo: ErrorInfo) => void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (error: any, errorInfo: ErrorInfo) => {\n const eventId = captureReactException(error, errorInfo);\n if (callback) {\n callback(error, errorInfo, eventId);\n }\n };\n}\n"],"names":["version","isError","captureException"],"mappings":";;;;;;AAMA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,YAAY,EAAmB;AAChE,EAAE,MAAM,aAAa,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AACnD,EAAE,OAAO,UAAA,KAAe,IAAA,IAAQ,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE,CAAA;AAC7D,CAAA;AACA;AACA;AACA;AACA;AACO,SAAS,QAAQ,CAAC,KAAK,EAA6B,KAAK,EAAe;AAC/E,EAAE,MAAM,UAAW,GAAE,IAAI,OAAO,EAAE,CAAA;AAClC;AACA,EAAE,SAAS,OAAO,CAAC,KAAK,EAA6B,KAAK,EAAe;AACzE;AACA;AACA,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC/B,MAAM,OAAM;AACZ,KAAI;AACJ,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AACrB,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAC3B,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACxC,KAAI;AACJ,IAAI,KAAK,CAAC,KAAM,GAAE,KAAK,CAAA;AACvB,GAAE;AACF;AACA,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACvB,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,qBAAqB;AACrC;AACA,EAAE,KAAK;AACP,EAAE,EAAE,gBAAgB;AACpB,EAAE,IAAI;AACN,EAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,IAAI,gBAAgB,CAACA,aAAO,CAAA,IAAKC,aAAO,CAAC,KAAK,CAAE,IAAG,cAAc,EAAE;AACrE,IAAI,MAAM,qBAAqB,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AACvD,IAAI,kBAAkB,CAAC,IAAA,GAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA,CAAA;AACA,IAAA,kBAAA,CAAA,KAAA,GAAA,cAAA,CAAA;AACA;AACA;AACA,IAAA,QAAA,CAAA,KAAA,EAAA,kBAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA,EAAA,OAAAC,wBAAA,CAAA,KAAA,EAAA;AACA,IAAA,GAAA,IAAA;AACA,IAAA,cAAA,EAAA;AACA,MAAA,QAAA,EAAA,EAAA,KAAA,EAAA,EAAA,cAAA,EAAA,EAAA;AACA,KAAA;AACA,GAAA,CAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA;AACA;AACA,EAAA,QAAA;AACA;AACA,EAAA;AACA;AACA,EAAA,OAAA,CAAA,KAAA,EAAA,SAAA,KAAA;AACA,IAAA,MAAA,OAAA,GAAA,qBAAA,CAAA,KAAA,EAAA,SAAA,CAAA,CAAA;AACA,IAAA,IAAA,QAAA,EAAA;AACA,MAAA,QAAA,CAAA,KAAA,EAAA,SAAA,EAAA,OAAA,CAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA;;;;;;;"}
|
package/cjs/errorboundary.js
CHANGED
|
@@ -6,6 +6,7 @@ const utils = require('@sentry/utils');
|
|
|
6
6
|
const hoistNonReactStatics = require('hoist-non-react-statics');
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const debugBuild = require('./debug-build.js');
|
|
9
|
+
const error = require('./error.js');
|
|
9
10
|
|
|
10
11
|
const _interopDefault = e => e && e.__esModule ? e.default : e;
|
|
11
12
|
|
|
@@ -24,11 +25,6 @@ function _interopNamespace(e) {
|
|
|
24
25
|
const hoistNonReactStatics__default = /*#__PURE__*/_interopDefault(hoistNonReactStatics);
|
|
25
26
|
const React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
27
|
|
|
27
|
-
function isAtLeastReact17(version) {
|
|
28
|
-
const major = version.match(/^([^.]+)/);
|
|
29
|
-
return major !== null && parseInt(major[0]) >= 17;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
28
|
const UNKNOWN_COMPONENT = 'unknown';
|
|
33
29
|
|
|
34
30
|
const INITIAL_STATE = {
|
|
@@ -37,25 +33,6 @@ const INITIAL_STATE = {
|
|
|
37
33
|
eventId: null,
|
|
38
34
|
};
|
|
39
35
|
|
|
40
|
-
function setCause(error, cause) {
|
|
41
|
-
const seenErrors = new WeakMap();
|
|
42
|
-
|
|
43
|
-
function recurse(error, cause) {
|
|
44
|
-
// If we've already seen the error, there is a recursive loop somewhere in the error's
|
|
45
|
-
// cause chain. Let's just bail out then to prevent a stack overflow.
|
|
46
|
-
if (seenErrors.has(error)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (error.cause) {
|
|
50
|
-
seenErrors.set(error, true);
|
|
51
|
-
return recurse(error.cause, cause);
|
|
52
|
-
}
|
|
53
|
-
error.cause = cause;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
recurse(error, cause);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
36
|
/**
|
|
60
37
|
* A ErrorBoundary component that logs errors to Sentry.
|
|
61
38
|
* NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the
|
|
@@ -80,41 +57,21 @@ class ErrorBoundary extends React__namespace.Component {
|
|
|
80
57
|
}
|
|
81
58
|
}
|
|
82
59
|
|
|
83
|
-
componentDidCatch(error,
|
|
60
|
+
componentDidCatch(error$1, errorInfo) {
|
|
61
|
+
const { componentStack } = errorInfo;
|
|
62
|
+
// TODO(v9): Remove this check and type `componentStack` to be React.ErrorInfo['componentStack'].
|
|
63
|
+
const passedInComponentStack = componentStack == null ? undefined : componentStack;
|
|
64
|
+
|
|
84
65
|
const { beforeCapture, onError, showDialog, dialogOptions } = this.props;
|
|
85
66
|
browser.withScope(scope => {
|
|
86
|
-
// If on React version >= 17, create stack trace from componentStack param and links
|
|
87
|
-
// to to the original error using `error.cause` otherwise relies on error param for stacktrace.
|
|
88
|
-
// Linking errors requires the `LinkedErrors` integration be enabled.
|
|
89
|
-
// See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks
|
|
90
|
-
//
|
|
91
|
-
// Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked
|
|
92
|
-
// with non-error objects. This is why we need to check if the error is an error-like object.
|
|
93
|
-
// See: https://github.com/getsentry/sentry-javascript/issues/6167
|
|
94
|
-
if (isAtLeastReact17(React__namespace.version) && utils.isError(error)) {
|
|
95
|
-
const errorBoundaryError = new Error(error.message);
|
|
96
|
-
errorBoundaryError.name = `React ErrorBoundary ${error.name}`;
|
|
97
|
-
errorBoundaryError.stack = componentStack;
|
|
98
|
-
|
|
99
|
-
// Using the `LinkedErrors` integration to link the errors together.
|
|
100
|
-
setCause(error, errorBoundaryError);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
67
|
if (beforeCapture) {
|
|
104
|
-
beforeCapture(scope, error,
|
|
68
|
+
beforeCapture(scope, error$1, passedInComponentStack);
|
|
105
69
|
}
|
|
106
70
|
|
|
107
|
-
const eventId =
|
|
108
|
-
captureContext: {
|
|
109
|
-
contexts: { react: { componentStack } },
|
|
110
|
-
},
|
|
111
|
-
// If users provide a fallback component we can assume they are handling the error.
|
|
112
|
-
// Therefore, we set the mechanism depending on the presence of the fallback prop.
|
|
113
|
-
mechanism: { handled: !!this.props.fallback },
|
|
114
|
-
});
|
|
71
|
+
const eventId = error.captureReactException(error$1, errorInfo, { mechanism: { handled: !!this.props.fallback } });
|
|
115
72
|
|
|
116
73
|
if (onError) {
|
|
117
|
-
onError(error,
|
|
74
|
+
onError(error$1, passedInComponentStack, eventId);
|
|
118
75
|
}
|
|
119
76
|
if (showDialog) {
|
|
120
77
|
this._lastEventId = eventId;
|
|
@@ -125,7 +82,7 @@ class ErrorBoundary extends React__namespace.Component {
|
|
|
125
82
|
|
|
126
83
|
// componentDidCatch is used over getDerivedStateFromError
|
|
127
84
|
// so that componentStack is accessible through state.
|
|
128
|
-
this.setState({ error, componentStack, eventId });
|
|
85
|
+
this.setState({ error: error$1, componentStack, eventId });
|
|
129
86
|
});
|
|
130
87
|
}
|
|
131
88
|
|
|
@@ -194,7 +151,6 @@ function withErrorBoundary(
|
|
|
194
151
|
WrappedComponent,
|
|
195
152
|
errorBoundaryOptions,
|
|
196
153
|
) {
|
|
197
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
198
154
|
const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;
|
|
199
155
|
|
|
200
156
|
const Wrapped = (props) => (
|
|
@@ -203,7 +159,6 @@ function withErrorBoundary(
|
|
|
203
159
|
})
|
|
204
160
|
);
|
|
205
161
|
|
|
206
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
207
162
|
Wrapped.displayName = `errorBoundary(${componentDisplayName})`;
|
|
208
163
|
|
|
209
164
|
// Copy over static methods from Wrapped component to Profiler HOC
|
|
@@ -214,6 +169,5 @@ function withErrorBoundary(
|
|
|
214
169
|
|
|
215
170
|
exports.ErrorBoundary = ErrorBoundary;
|
|
216
171
|
exports.UNKNOWN_COMPONENT = UNKNOWN_COMPONENT;
|
|
217
|
-
exports.isAtLeastReact17 = isAtLeastReact17;
|
|
218
172
|
exports.withErrorBoundary = withErrorBoundary;
|
|
219
173
|
//# sourceMappingURL=errorboundary.js.map
|
package/cjs/errorboundary.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { captureException, getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/types';\nimport { isError, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\n\nexport function isAtLeastReact17(version: string): boolean {\n const major = version.match(/^([^.]+)/);\n return major !== null && parseInt(major[0]) >= 17;\n}\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: unknown;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: ReportDialogOptions | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: unknown;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\nfunction setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakMap<Error, boolean>();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.set(error, true);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: unknown, { componentStack }: React.ErrorInfo): void {\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(React.version) && isError(error)) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n if (beforeCapture) {\n beforeCapture(scope, error, componentStack);\n }\n\n const eventId = captureException(error, {\n captureContext: {\n contexts: { react: { componentStack } },\n },\n // If users provide a fallback component we can assume they are handling the error.\n // Therefore, we set the mechanism depending on the presence of the fallback prop.\n mechanism: { handled: !!this.props.fallback },\n });\n\n if (onError) {\n onError(error, componentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = React.createElement(fallback, {\n error: state.error,\n componentStack: state.componentStack as string,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId as string,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["React","getClient","showReportDialog","withScope","isError","captureException","DEBUG_BUILD","logger","_jsx","hoistNonReactStatics"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { captureReactException } from './error';\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: unknown;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: ReportDialogOptions | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: unknown, componentStack: string | undefined, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: unknown;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: unknown, errorInfo: React.ErrorInfo): void {\n const { componentStack } = errorInfo;\n // TODO(v9): Remove this check and type `componentStack` to be React.ErrorInfo['componentStack'].\n const passedInComponentStack: string | undefined = componentStack == null ? undefined : componentStack;\n\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n if (beforeCapture) {\n beforeCapture(scope, error, passedInComponentStack);\n }\n\n const eventId = captureReactException(error, errorInfo, { mechanism: { handled: !!this.props.fallback } });\n\n if (onError) {\n onError(error, passedInComponentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = React.createElement(fallback, {\n error: state.error,\n componentStack: state.componentStack as string,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId as string,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["React","getClient","showReportDialog","error","withScope","captureReactException","DEBUG_BUILD","logger","_jsx","hoistNonReactStatics"],"mappings":"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"}
|
package/cjs/index.js
CHANGED
|
@@ -2,6 +2,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
2
2
|
|
|
3
3
|
const browser = require('@sentry/browser');
|
|
4
4
|
const sdk = require('./sdk.js');
|
|
5
|
+
const error = require('./error.js');
|
|
5
6
|
const profiler = require('./profiler.js');
|
|
6
7
|
const errorboundary = require('./errorboundary.js');
|
|
7
8
|
const redux = require('./redux.js');
|
|
@@ -12,6 +13,7 @@ const reactrouterv6 = require('./reactrouterv6.js');
|
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
exports.init = sdk.init;
|
|
16
|
+
exports.reactErrorHandler = error.reactErrorHandler;
|
|
15
17
|
exports.Profiler = profiler.Profiler;
|
|
16
18
|
exports.useProfiler = profiler.useProfiler;
|
|
17
19
|
exports.withProfiler = profiler.withProfiler;
|
package/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/esm/error.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { captureException } from '@sentry/browser';
|
|
2
|
+
import { isError } from '@sentry/utils';
|
|
3
|
+
import { version } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* See if React major version is 17+ by parsing version string.
|
|
7
|
+
*/
|
|
8
|
+
function isAtLeastReact17(reactVersion) {
|
|
9
|
+
const reactMajor = reactVersion.match(/^([^.]+)/);
|
|
10
|
+
return reactMajor !== null && parseInt(reactMajor[0]) >= 17;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Recurse through `error.cause` chain to set cause on an error.
|
|
15
|
+
*/
|
|
16
|
+
function setCause(error, cause) {
|
|
17
|
+
const seenErrors = new WeakSet();
|
|
18
|
+
|
|
19
|
+
function recurse(error, cause) {
|
|
20
|
+
// If we've already seen the error, there is a recursive loop somewhere in the error's
|
|
21
|
+
// cause chain. Let's just bail out then to prevent a stack overflow.
|
|
22
|
+
if (seenErrors.has(error)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (error.cause) {
|
|
26
|
+
seenErrors.add(error);
|
|
27
|
+
return recurse(error.cause, cause);
|
|
28
|
+
}
|
|
29
|
+
error.cause = cause;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
recurse(error, cause);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Captures an error that was thrown by a React ErrorBoundary or React root.
|
|
37
|
+
*
|
|
38
|
+
* @param error The error to capture.
|
|
39
|
+
* @param errorInfo The errorInfo provided by React.
|
|
40
|
+
* @param hint Optional additional data to attach to the Sentry event.
|
|
41
|
+
* @returns the id of the captured Sentry event.
|
|
42
|
+
*/
|
|
43
|
+
function captureReactException(
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
error,
|
|
46
|
+
{ componentStack },
|
|
47
|
+
hint,
|
|
48
|
+
) {
|
|
49
|
+
// If on React version >= 17, create stack trace from componentStack param and links
|
|
50
|
+
// to to the original error using `error.cause` otherwise relies on error param for stacktrace.
|
|
51
|
+
// Linking errors requires the `LinkedErrors` integration be enabled.
|
|
52
|
+
// See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks
|
|
53
|
+
//
|
|
54
|
+
// Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked
|
|
55
|
+
// with non-error objects. This is why we need to check if the error is an error-like object.
|
|
56
|
+
// See: https://github.com/getsentry/sentry-javascript/issues/6167
|
|
57
|
+
if (isAtLeastReact17(version) && isError(error) && componentStack) {
|
|
58
|
+
const errorBoundaryError = new Error(error.message);
|
|
59
|
+
errorBoundaryError.name = `React ErrorBoundary ${error.name}`;
|
|
60
|
+
errorBoundaryError.stack = componentStack;
|
|
61
|
+
|
|
62
|
+
// Using the `LinkedErrors` integration to link the errors together.
|
|
63
|
+
setCause(error, errorBoundaryError);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return captureException(error, {
|
|
67
|
+
...hint,
|
|
68
|
+
captureContext: {
|
|
69
|
+
contexts: { react: { componentStack } },
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,
|
|
76
|
+
* and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.
|
|
77
|
+
*
|
|
78
|
+
* @param callback An optional callback that will be called after the error is captured.
|
|
79
|
+
* Use this to add custom handling for errors.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
*
|
|
83
|
+
* ```JavaScript
|
|
84
|
+
* const root = createRoot(container, {
|
|
85
|
+
* onCaughtError: Sentry.reactErrorHandler(),
|
|
86
|
+
* onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
|
|
87
|
+
* console.warn('Caught error', error, errorInfo.componentStack);
|
|
88
|
+
* });
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
function reactErrorHandler(
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
94
|
+
callback,
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
+
) {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
return (error, errorInfo) => {
|
|
99
|
+
const eventId = captureReactException(error, errorInfo);
|
|
100
|
+
if (callback) {
|
|
101
|
+
callback(error, errorInfo, eventId);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { captureReactException, isAtLeastReact17, reactErrorHandler, setCause };
|
|
107
|
+
//# sourceMappingURL=error.js.map
|
package/esm/error.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sources":["../../src/error.ts"],"sourcesContent":["import { captureException } from '@sentry/browser';\nimport type { EventHint } from '@sentry/types';\nimport { isError } from '@sentry/utils';\nimport { version } from 'react';\nimport type { ErrorInfo } from 'react';\n\n/**\n * See if React major version is 17+ by parsing version string.\n */\nexport function isAtLeastReact17(reactVersion: string): boolean {\n const reactMajor = reactVersion.match(/^([^.]+)/);\n return reactMajor !== null && parseInt(reactMajor[0]) >= 17;\n}\n\n/**\n * Recurse through `error.cause` chain to set cause on an error.\n */\nexport function setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakSet();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.add(error);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * Captures an error that was thrown by a React ErrorBoundary or React root.\n *\n * @param error The error to capture.\n * @param errorInfo The errorInfo provided by React.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nexport function captureReactException(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n { componentStack }: ErrorInfo,\n hint?: EventHint,\n): string {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(version) && isError(error) && componentStack) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n return captureException(error, {\n ...hint,\n captureContext: {\n contexts: { react: { componentStack } },\n },\n });\n}\n\n/**\n * Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,\n * and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.\n *\n * @param callback An optional callback that will be called after the error is captured.\n * Use this to add custom handling for errors.\n *\n * @example\n *\n * ```JavaScript\n * const root = createRoot(container, {\n * onCaughtError: Sentry.reactErrorHandler(),\n * onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {\n * console.warn('Caught error', error, errorInfo.componentStack);\n * });\n * });\n * ```\n */\nexport function reactErrorHandler(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback?: (error: any, errorInfo: ErrorInfo, eventId: string) => void,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): (error: any, errorInfo: ErrorInfo) => void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (error: any, errorInfo: ErrorInfo) => {\n const eventId = captureReactException(error, errorInfo);\n if (callback) {\n callback(error, errorInfo, eventId);\n }\n };\n}\n"],"names":[],"mappings":";;;;AAMA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,YAAY,EAAmB;AAChE,EAAE,MAAM,aAAa,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AACnD,EAAE,OAAO,UAAA,KAAe,IAAA,IAAQ,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE,CAAA;AAC7D,CAAA;AACA;AACA;AACA;AACA;AACO,SAAS,QAAQ,CAAC,KAAK,EAA6B,KAAK,EAAe;AAC/E,EAAE,MAAM,UAAW,GAAE,IAAI,OAAO,EAAE,CAAA;AAClC;AACA,EAAE,SAAS,OAAO,CAAC,KAAK,EAA6B,KAAK,EAAe;AACzE;AACA;AACA,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC/B,MAAM,OAAM;AACZ,KAAI;AACJ,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AACrB,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAC3B,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACxC,KAAI;AACJ,IAAI,KAAK,CAAC,KAAM,GAAE,KAAK,CAAA;AACvB,GAAE;AACF;AACA,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACvB,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,qBAAqB;AACrC;AACA,EAAE,KAAK;AACP,EAAE,EAAE,gBAAgB;AACpB,EAAE,IAAI;AACN,EAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,IAAI,gBAAgB,CAAC,OAAO,CAAA,IAAK,OAAO,CAAC,KAAK,CAAE,IAAG,cAAc,EAAE;AACrE,IAAI,MAAM,qBAAqB,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AACvD,IAAI,kBAAkB,CAAC,IAAA,GAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA,CAAA;AACA,IAAA,kBAAA,CAAA,KAAA,GAAA,cAAA,CAAA;AACA;AACA;AACA,IAAA,QAAA,CAAA,KAAA,EAAA,kBAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA,EAAA,OAAA,gBAAA,CAAA,KAAA,EAAA;AACA,IAAA,GAAA,IAAA;AACA,IAAA,cAAA,EAAA;AACA,MAAA,QAAA,EAAA,EAAA,KAAA,EAAA,EAAA,cAAA,EAAA,EAAA;AACA,KAAA;AACA,GAAA,CAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA;AACA;AACA,EAAA,QAAA;AACA;AACA,EAAA;AACA;AACA,EAAA,OAAA,CAAA,KAAA,EAAA,SAAA,KAAA;AACA,IAAA,MAAA,OAAA,GAAA,qBAAA,CAAA,KAAA,EAAA,SAAA,CAAA,CAAA;AACA,IAAA,IAAA,QAAA,EAAA;AACA,MAAA,QAAA,CAAA,KAAA,EAAA,SAAA,EAAA,OAAA,CAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA;;;;"}
|
package/esm/errorboundary.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { getClient, showReportDialog, withScope
|
|
3
|
-
import {
|
|
2
|
+
import { getClient, showReportDialog, withScope } from '@sentry/browser';
|
|
3
|
+
import { logger } from '@sentry/utils';
|
|
4
4
|
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import { DEBUG_BUILD } from './debug-build.js';
|
|
7
|
-
|
|
8
|
-
function isAtLeastReact17(version) {
|
|
9
|
-
const major = version.match(/^([^.]+)/);
|
|
10
|
-
return major !== null && parseInt(major[0]) >= 17;
|
|
11
|
-
}
|
|
7
|
+
import { captureReactException } from './error.js';
|
|
12
8
|
|
|
13
9
|
const UNKNOWN_COMPONENT = 'unknown';
|
|
14
10
|
|
|
@@ -18,25 +14,6 @@ const INITIAL_STATE = {
|
|
|
18
14
|
eventId: null,
|
|
19
15
|
};
|
|
20
16
|
|
|
21
|
-
function setCause(error, cause) {
|
|
22
|
-
const seenErrors = new WeakMap();
|
|
23
|
-
|
|
24
|
-
function recurse(error, cause) {
|
|
25
|
-
// If we've already seen the error, there is a recursive loop somewhere in the error's
|
|
26
|
-
// cause chain. Let's just bail out then to prevent a stack overflow.
|
|
27
|
-
if (seenErrors.has(error)) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (error.cause) {
|
|
31
|
-
seenErrors.set(error, true);
|
|
32
|
-
return recurse(error.cause, cause);
|
|
33
|
-
}
|
|
34
|
-
error.cause = cause;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
recurse(error, cause);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
17
|
/**
|
|
41
18
|
* A ErrorBoundary component that logs errors to Sentry.
|
|
42
19
|
* NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the
|
|
@@ -61,41 +38,21 @@ class ErrorBoundary extends React.Component {
|
|
|
61
38
|
}
|
|
62
39
|
}
|
|
63
40
|
|
|
64
|
-
componentDidCatch(error,
|
|
41
|
+
componentDidCatch(error, errorInfo) {
|
|
42
|
+
const { componentStack } = errorInfo;
|
|
43
|
+
// TODO(v9): Remove this check and type `componentStack` to be React.ErrorInfo['componentStack'].
|
|
44
|
+
const passedInComponentStack = componentStack == null ? undefined : componentStack;
|
|
45
|
+
|
|
65
46
|
const { beforeCapture, onError, showDialog, dialogOptions } = this.props;
|
|
66
47
|
withScope(scope => {
|
|
67
|
-
// If on React version >= 17, create stack trace from componentStack param and links
|
|
68
|
-
// to to the original error using `error.cause` otherwise relies on error param for stacktrace.
|
|
69
|
-
// Linking errors requires the `LinkedErrors` integration be enabled.
|
|
70
|
-
// See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks
|
|
71
|
-
//
|
|
72
|
-
// Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked
|
|
73
|
-
// with non-error objects. This is why we need to check if the error is an error-like object.
|
|
74
|
-
// See: https://github.com/getsentry/sentry-javascript/issues/6167
|
|
75
|
-
if (isAtLeastReact17(React.version) && isError(error)) {
|
|
76
|
-
const errorBoundaryError = new Error(error.message);
|
|
77
|
-
errorBoundaryError.name = `React ErrorBoundary ${error.name}`;
|
|
78
|
-
errorBoundaryError.stack = componentStack;
|
|
79
|
-
|
|
80
|
-
// Using the `LinkedErrors` integration to link the errors together.
|
|
81
|
-
setCause(error, errorBoundaryError);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
48
|
if (beforeCapture) {
|
|
85
|
-
beforeCapture(scope, error,
|
|
49
|
+
beforeCapture(scope, error, passedInComponentStack);
|
|
86
50
|
}
|
|
87
51
|
|
|
88
|
-
const eventId =
|
|
89
|
-
captureContext: {
|
|
90
|
-
contexts: { react: { componentStack } },
|
|
91
|
-
},
|
|
92
|
-
// If users provide a fallback component we can assume they are handling the error.
|
|
93
|
-
// Therefore, we set the mechanism depending on the presence of the fallback prop.
|
|
94
|
-
mechanism: { handled: !!this.props.fallback },
|
|
95
|
-
});
|
|
52
|
+
const eventId = captureReactException(error, errorInfo, { mechanism: { handled: !!this.props.fallback } });
|
|
96
53
|
|
|
97
54
|
if (onError) {
|
|
98
|
-
onError(error,
|
|
55
|
+
onError(error, passedInComponentStack, eventId);
|
|
99
56
|
}
|
|
100
57
|
if (showDialog) {
|
|
101
58
|
this._lastEventId = eventId;
|
|
@@ -175,7 +132,6 @@ function withErrorBoundary(
|
|
|
175
132
|
WrappedComponent,
|
|
176
133
|
errorBoundaryOptions,
|
|
177
134
|
) {
|
|
178
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
179
135
|
const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;
|
|
180
136
|
|
|
181
137
|
const Wrapped = (props) => (
|
|
@@ -184,7 +140,6 @@ function withErrorBoundary(
|
|
|
184
140
|
})
|
|
185
141
|
);
|
|
186
142
|
|
|
187
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
188
143
|
Wrapped.displayName = `errorBoundary(${componentDisplayName})`;
|
|
189
144
|
|
|
190
145
|
// Copy over static methods from Wrapped component to Profiler HOC
|
|
@@ -193,5 +148,5 @@ function withErrorBoundary(
|
|
|
193
148
|
return Wrapped;
|
|
194
149
|
}
|
|
195
150
|
|
|
196
|
-
export { ErrorBoundary, UNKNOWN_COMPONENT,
|
|
151
|
+
export { ErrorBoundary, UNKNOWN_COMPONENT, withErrorBoundary };
|
|
197
152
|
//# sourceMappingURL=errorboundary.js.map
|
package/esm/errorboundary.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { captureException, getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/types';\nimport { isError, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\n\nexport function isAtLeastReact17(version: string): boolean {\n const major = version.match(/^([^.]+)/);\n return major !== null && parseInt(major[0]) >= 17;\n}\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: unknown;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: ReportDialogOptions | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: unknown;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\nfunction setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakMap<Error, boolean>();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.set(error, true);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: unknown, { componentStack }: React.ErrorInfo): void {\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(React.version) && isError(error)) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n if (beforeCapture) {\n beforeCapture(scope, error, componentStack);\n }\n\n const eventId = captureException(error, {\n captureContext: {\n contexts: { react: { componentStack } },\n },\n // If users provide a fallback component we can assume they are handling the error.\n // Therefore, we set the mechanism depending on the presence of the fallback prop.\n mechanism: { handled: !!this.props.fallback },\n });\n\n if (onError) {\n onError(error, componentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = React.createElement(fallback, {\n error: state.error,\n componentStack: state.componentStack as string,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId as string,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["_jsx"],"mappings":";;;;;;;AASO,SAAS,gBAAgB,CAAC,OAAO,EAAmB;AAC3D,EAAE,MAAM,QAAQ,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AACzC,EAAE,OAAO,KAAA,KAAU,IAAA,IAAQ,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE,CAAA;AACnD,CAAA;AACA;AACO,MAAM,iBAAkB,GAAE,UAAS;;AAmD1C,MAAM,gBAAgB;AACtB,EAAE,cAAc,EAAE,IAAI;AACtB,EAAE,KAAK,EAAE,IAAI;AACb,EAAE,OAAO,EAAE,IAAI;AACf,CAAC,CAAA;AACD;AACA,SAAS,QAAQ,CAAC,KAAK,EAA6B,KAAK,EAAe;AACxE,EAAE,MAAM,UAAW,GAAE,IAAI,OAAO,EAAkB,CAAA;AAClD;AACA,EAAE,SAAS,OAAO,CAAC,KAAK,EAA6B,KAAK,EAAe;AACzE;AACA;AACA,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC/B,MAAM,OAAM;AACZ,KAAI;AACJ,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AACrB,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACjC,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACxC,KAAI;AACJ,IAAI,KAAK,CAAC,KAAM,GAAE,KAAK,CAAA;AACvB,GAAE;AACF;AACA,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACvB,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAyC;;AAOpF,GAAS,WAAW,CAAC,KAAK,EAAsB;AAChD,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA,aAAA,CAAA,SAAA,CAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAChB;AACA,IAAI,IAAI,CAAC,KAAM,GAAE,aAAa,CAAA;AAC9B,IAAI,IAAI,CAAC,yBAA0B,GAAE,IAAI,CAAA;AACzC;AACA,IAAI,MAAM,MAAA,GAAS,SAAS,EAAE,CAAA;AAC9B,IAAI,IAAI,MAAA,IAAU,KAAK,CAAC,UAAU,EAAE;AACpC,MAAM,IAAI,CAAC,yBAA0B,GAAE,KAAK,CAAA;AAC5C,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,SAAS;AAC3C,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAA,IAAQ,IAAI,CAAC,YAAa,IAAG,KAAK,CAAC,QAAA,KAAa,IAAI,CAAC,YAAY,EAAE;AACtF,UAAU,gBAAgB,CAAC,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,YAAA,EAAc,CAAC,CAAA;AAClF,SAAQ;AACR,OAAO,CAAC,CAAA;AACR,KAAI;AACJ,GAAE;AACF;AACA,GAAS,iBAAiB,CAAC,KAAK,EAAW,EAAE,cAAA,EAAgB,EAAyB;AACtF,IAAI,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,aAAc,EAAA,GAAI,IAAI,CAAC,KAAK,CAAA;AAC5E,IAAI,SAAS,CAAC,KAAA,IAAS;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAA,IAAK,OAAO,CAAC,KAAK,CAAC,EAAE;AAC7D,QAAQ,MAAM,qBAAqB,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC3D,QAAQ,kBAAkB,CAAC,IAAA,GAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA,CAAA;AACA,QAAA,kBAAA,CAAA,KAAA,GAAA,cAAA,CAAA;AACA;AACA;AACA,QAAA,QAAA,CAAA,KAAA,EAAA,kBAAA,CAAA,CAAA;AACA,OAAA;AACA;AACA,MAAA,IAAA,aAAA,EAAA;AACA,QAAA,aAAA,CAAA,KAAA,EAAA,KAAA,EAAA,cAAA,CAAA,CAAA;AACA,OAAA;AACA;AACA,MAAA,MAAA,OAAA,GAAA,gBAAA,CAAA,KAAA,EAAA;AACA,QAAA,cAAA,EAAA;AACA,UAAA,QAAA,EAAA,EAAA,KAAA,EAAA,EAAA,cAAA,EAAA,EAAA;AACA,SAAA;AACA;AACA;AACA,QAAA,SAAA,EAAA,EAAA,OAAA,EAAA,CAAA,CAAA,IAAA,CAAA,KAAA,CAAA,QAAA,EAAA;AACA,OAAA,CAAA,CAAA;AACA;AACA,MAAA,IAAA,OAAA,EAAA;AACA,QAAA,OAAA,CAAA,KAAA,EAAA,cAAA,EAAA,OAAA,CAAA,CAAA;AACA,OAAA;AACA,MAAA,IAAA,UAAA,EAAA;AACA,QAAA,IAAA,CAAA,YAAA,GAAA,OAAA,CAAA;AACA,QAAA,IAAA,IAAA,CAAA,yBAAA,EAAA;AACA,UAAA,gBAAA,CAAA,EAAA,GAAA,aAAA,EAAA,OAAA,EAAA,CAAA,CAAA;AACA,SAAA;AACA,OAAA;AACA;AACA;AACA;AACA,MAAA,IAAA,CAAA,QAAA,CAAA,EAAA,KAAA,EAAA,cAAA,EAAA,OAAA,EAAA,CAAA,CAAA;AACA,KAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA,GAAA,iBAAA,GAAA;AACA,IAAA,MAAA,EAAA,OAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,IAAA,OAAA,EAAA;AACA,MAAA,OAAA,EAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;AACA,GAAA,oBAAA,GAAA;AACA,IAAA,MAAA,EAAA,KAAA,EAAA,cAAA,EAAA,OAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,EAAA,SAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,IAAA,SAAA,EAAA;AACA,MAAA,SAAA,CAAA,KAAA,EAAA,cAAA,EAAA,OAAA,CAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;AACA,GAAA,MAAA,GAAA,CAAA,IAAA,CAAA,kBAAA,GAAA,MAAA;AACA,IAAA,MAAA,EAAA,OAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,EAAA,KAAA,EAAA,cAAA,EAAA,OAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,IAAA,OAAA,EAAA;AACA,MAAA,OAAA,CAAA,KAAA,EAAA,cAAA,EAAA,OAAA,CAAA,CAAA;AACA,KAAA;AACA,IAAA,IAAA,CAAA,QAAA,CAAA,aAAA,CAAA,CAAA;AACA,IAAA,CAAA;AACA;AACA,GAAA,MAAA,GAAA;AACA,IAAA,MAAA,EAAA,QAAA,EAAA,QAAA,EAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,KAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AACA;AACA,IAAA,IAAA,KAAA,CAAA,KAAA,EAAA;AACA,MAAA,IAAA,OAAA,GAAA,SAAA,CAAA;AACA,MAAA,IAAA,OAAA,QAAA,KAAA,UAAA,EAAA;AACA,QAAA,OAAA,GAAA,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AACA,UAAA,KAAA,EAAA,KAAA,CAAA,KAAA;AACA,UAAA,cAAA,EAAA,KAAA,CAAA,cAAA;AACA,UAAA,UAAA,EAAA,IAAA,CAAA,kBAAA;AACA,UAAA,OAAA,EAAA,KAAA,CAAA,OAAA;AACA,SAAA,CAAA,CAAA;AACA,OAAA,MAAA;AACA,QAAA,OAAA,GAAA,QAAA,CAAA;AACA,OAAA;AACA;AACA,MAAA,IAAA,KAAA,CAAA,cAAA,CAAA,OAAA,CAAA,EAAA;AACA,QAAA,OAAA,OAAA,CAAA;AACA,OAAA;AACA;AACA,MAAA,IAAA,QAAA,EAAA;AACA,QAAA,WAAA,IAAA,MAAA,CAAA,IAAA,CAAA,+CAAA,CAAA,CAAA;AACA,OAAA;AACA;AACA;AACA,MAAA,OAAA,IAAA,CAAA;AACA,KAAA;AACA;AACA,IAAA,IAAA,OAAA,QAAA,KAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAA,QAAA,IAAA,CAAA;AACA,KAAA;AACA,IAAA,OAAA,QAAA,CAAA;AACA,GAAA;AACA,CAAA;AACA;AACA;AACA,SAAA,iBAAA;AACA,EAAA,gBAAA;AACA,EAAA,oBAAA;AACA,EAAA;AACA;AACA,EAAA,MAAA,oBAAA,GAAA,gBAAA,CAAA,WAAA,IAAA,gBAAA,CAAA,IAAA,IAAA,iBAAA,CAAA;AACA;AACA,EAAA,MAAA,OAAA,GAAA,CAAA,KAAA;AACA,IAAAA,GAAA,CAAA,aAAA,EAAA,EAAA,GAAA,oBAAA,EAAA,QAAA;AACA,MAAAA,GAAA,CAAA,gBAAA,EAAA,EAAA,GAAA,KAAA,EAAA,EAAA;AACA,KAAA,CAAA;AACA,GAAA,CAAA;AACA;AACA;AACA,EAAA,OAAA,CAAA,WAAA,GAAA,CAAA,cAAA,EAAA,oBAAA,CAAA,CAAA,CAAA,CAAA;AACA;AACA;AACA;AACA,EAAA,oBAAA,CAAA,OAAA,EAAA,gBAAA,CAAA,CAAA;AACA,EAAA,OAAA,OAAA,CAAA;AACA;;;;"}
|
|
1
|
+
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { captureReactException } from './error';\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: unknown;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: ReportDialogOptions | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: unknown, componentStack: string | undefined, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: unknown;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: unknown, errorInfo: React.ErrorInfo): void {\n const { componentStack } = errorInfo;\n // TODO(v9): Remove this check and type `componentStack` to be React.ErrorInfo['componentStack'].\n const passedInComponentStack: string | undefined = componentStack == null ? undefined : componentStack;\n\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n if (beforeCapture) {\n beforeCapture(scope, error, passedInComponentStack);\n }\n\n const eventId = captureReactException(error, errorInfo, { mechanism: { handled: !!this.props.fallback } });\n\n if (onError) {\n onError(error, passedInComponentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = React.createElement(fallback, {\n error: state.error,\n componentStack: state.componentStack as string,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId as string,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["_jsx"],"mappings":"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"}
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/browser';
|
|
2
2
|
export { init } from './sdk.js';
|
|
3
|
+
export { reactErrorHandler } from './error.js';
|
|
3
4
|
export { Profiler, useProfiler, withProfiler } from './profiler.js';
|
|
4
5
|
export { ErrorBoundary, withErrorBoundary } from './errorboundary.js';
|
|
5
6
|
export { createReduxEnhancer } from './redux.js';
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/react",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"description": "Official Sentry SDK for React.js",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@sentry/browser": "8.
|
|
46
|
-
"@sentry/core": "8.
|
|
47
|
-
"@sentry/types": "8.
|
|
48
|
-
"@sentry/utils": "8.
|
|
45
|
+
"@sentry/browser": "8.6.0",
|
|
46
|
+
"@sentry/core": "8.6.0",
|
|
47
|
+
"@sentry/types": "8.6.0",
|
|
48
|
+
"@sentry/utils": "8.6.0",
|
|
49
49
|
"hoist-non-react-statics": "^3.3.2"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"@testing-library/react-hooks": "^7.0.2",
|
|
57
57
|
"@types/history-4": "npm:@types/history@4.7.8",
|
|
58
58
|
"@types/history-5": "npm:@types/history@4.7.8",
|
|
59
|
-
"@types/hoist-non-react-statics": "^3.3.
|
|
59
|
+
"@types/hoist-non-react-statics": "^3.3.5",
|
|
60
60
|
"@types/node-fetch": "^2.6.0",
|
|
61
|
-
"@types/react": "
|
|
61
|
+
"@types/react": "17.0.3",
|
|
62
62
|
"@types/react-router-3": "npm:@types/react-router@3.0.24",
|
|
63
63
|
"@types/react-router-4": "npm:@types/react-router@5.1.14",
|
|
64
64
|
"@types/react-router-5": "npm:@types/react-router@5.1.14",
|
package/types/error.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { EventHint } from '@sentry/types';
|
|
2
|
+
import type { ErrorInfo } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* See if React major version is 17+ by parsing version string.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isAtLeastReact17(reactVersion: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Recurse through `error.cause` chain to set cause on an error.
|
|
9
|
+
*/
|
|
10
|
+
export declare function setCause(error: Error & {
|
|
11
|
+
cause?: Error;
|
|
12
|
+
}, cause: Error): void;
|
|
13
|
+
/**
|
|
14
|
+
* Captures an error that was thrown by a React ErrorBoundary or React root.
|
|
15
|
+
*
|
|
16
|
+
* @param error The error to capture.
|
|
17
|
+
* @param errorInfo The errorInfo provided by React.
|
|
18
|
+
* @param hint Optional additional data to attach to the Sentry event.
|
|
19
|
+
* @returns the id of the captured Sentry event.
|
|
20
|
+
*/
|
|
21
|
+
export declare function captureReactException(error: any, { componentStack }: ErrorInfo, hint?: EventHint): string;
|
|
22
|
+
/**
|
|
23
|
+
* Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,
|
|
24
|
+
* and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.
|
|
25
|
+
*
|
|
26
|
+
* @param callback An optional callback that will be called after the error is captured.
|
|
27
|
+
* Use this to add custom handling for errors.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
*
|
|
31
|
+
* ```JavaScript
|
|
32
|
+
* const root = createRoot(container, {
|
|
33
|
+
* onCaughtError: Sentry.reactErrorHandler(),
|
|
34
|
+
* onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
|
|
35
|
+
* console.warn('Caught error', error, errorInfo.componentStack);
|
|
36
|
+
* });
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function reactErrorHandler(callback?: (error: any, errorInfo: ErrorInfo, eventId: string) => void): (error: any, errorInfo: ErrorInfo) => void;
|
|
41
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAiB7E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAEnC,KAAK,EAAE,GAAG,EACV,EAAE,cAAc,EAAE,EAAE,SAAS,EAC7B,IAAI,CAAC,EAAE,SAAS,GACf,MAAM,CAwBR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAE/B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAErE,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,KAAK,IAAI,CAQ5C"}
|
package/types/errorboundary.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ReportDialogOptions } from '@sentry/browser';
|
|
2
2
|
import type { Scope } from '@sentry/types';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
export declare function isAtLeastReact17(version: string): boolean;
|
|
5
4
|
export declare const UNKNOWN_COMPONENT = "unknown";
|
|
6
5
|
export type FallbackRender = (errorData: {
|
|
7
6
|
error: unknown;
|
|
@@ -28,13 +27,13 @@ export type ErrorBoundaryProps = {
|
|
|
28
27
|
*/
|
|
29
28
|
fallback?: React.ReactElement | FallbackRender | undefined;
|
|
30
29
|
/** Called when the error boundary encounters an error */
|
|
31
|
-
onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;
|
|
30
|
+
onError?: ((error: unknown, componentStack: string | undefined, eventId: string) => void) | undefined;
|
|
32
31
|
/** Called on componentDidMount() */
|
|
33
32
|
onMount?: (() => void) | undefined;
|
|
34
33
|
/** Called if resetError() is called from the fallback render props function */
|
|
35
|
-
onReset?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
|
|
34
|
+
onReset?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;
|
|
36
35
|
/** Called on componentWillUnmount() */
|
|
37
|
-
onUnmount?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
|
|
36
|
+
onUnmount?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;
|
|
38
37
|
/** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */
|
|
39
38
|
beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;
|
|
40
39
|
};
|
|
@@ -58,7 +57,7 @@ declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBou
|
|
|
58
57
|
private readonly _openFallbackReportDialog;
|
|
59
58
|
private _lastEventId?;
|
|
60
59
|
constructor(props: ErrorBoundaryProps);
|
|
61
|
-
componentDidCatch(error: unknown,
|
|
60
|
+
componentDidCatch(error: unknown, errorInfo: React.ErrorInfo): void;
|
|
62
61
|
componentDidMount(): void;
|
|
63
62
|
componentWillUnmount(): void;
|
|
64
63
|
resetErrorBoundary: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorboundary.d.ts","sourceRoot":"","sources":["../../src/errorboundary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"errorboundary.d.ts","sourceRoot":"","sources":["../../src/errorboundary.tsx"],"names":[],"mappings":"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"}
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/browser';
|
|
2
2
|
export { init } from './sdk';
|
|
3
|
+
export { reactErrorHandler } from './error';
|
|
3
4
|
export { Profiler, withProfiler, useProfiler } from './profiler';
|
|
4
5
|
export type { ErrorBoundaryProps, FallbackRender } from './errorboundary';
|
|
5
6
|
export { ErrorBoundary, withErrorBoundary } from './errorboundary';
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,sCAAsC,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EACL,iBAAiB,EACjB,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sCAAsC,EACtC,8BAA8B,EAC9B,aAAa,EACb,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,sCAAsC,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EACL,iBAAiB,EACjB,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sCAAsC,EACtC,8BAA8B,EAC9B,aAAa,EACb,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EventHint } from '@sentry/types';
|
|
2
|
+
import { ErrorInfo } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* See if React major version is 17+ by parsing version string.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isAtLeastReact17(reactVersion: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Recurse through `error.cause` chain to set cause on an error.
|
|
9
|
+
*/
|
|
10
|
+
export declare function setCause(error: Error & {
|
|
11
|
+
cause?: Error;
|
|
12
|
+
}, cause: Error): void;
|
|
13
|
+
/**
|
|
14
|
+
* Captures an error that was thrown by a React ErrorBoundary or React root.
|
|
15
|
+
*
|
|
16
|
+
* @param error The error to capture.
|
|
17
|
+
* @param errorInfo The errorInfo provided by React.
|
|
18
|
+
* @param hint Optional additional data to attach to the Sentry event.
|
|
19
|
+
* @returns the id of the captured Sentry event.
|
|
20
|
+
*/
|
|
21
|
+
export declare function captureReactException(error: any, { componentStack }: ErrorInfo, hint?: EventHint): string;
|
|
22
|
+
/**
|
|
23
|
+
* Creates an error handler that can be used with the `onCaughtError`, `onUncaughtError`,
|
|
24
|
+
* and `onRecoverableError` options in `createRoot` and `hydrateRoot` React DOM methods.
|
|
25
|
+
*
|
|
26
|
+
* @param callback An optional callback that will be called after the error is captured.
|
|
27
|
+
* Use this to add custom handling for errors.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
*
|
|
31
|
+
* ```JavaScript
|
|
32
|
+
* const root = createRoot(container, {
|
|
33
|
+
* onCaughtError: Sentry.reactErrorHandler(),
|
|
34
|
+
* onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
|
|
35
|
+
* console.warn('Caught error', error, errorInfo.componentStack);
|
|
36
|
+
* });
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function reactErrorHandler(callback?: (error: any, errorInfo: ErrorInfo, eventId: string) => void): (error: any, errorInfo: ErrorInfo) => void;
|
|
41
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ReportDialogOptions } from '@sentry/browser';
|
|
2
2
|
import { Scope } from '@sentry/types';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
export declare function isAtLeastReact17(version: string): boolean;
|
|
5
4
|
export declare const UNKNOWN_COMPONENT = "unknown";
|
|
6
5
|
export type FallbackRender = (errorData: {
|
|
7
6
|
error: unknown;
|
|
@@ -28,13 +27,13 @@ export type ErrorBoundaryProps = {
|
|
|
28
27
|
*/
|
|
29
28
|
fallback?: React.ReactElement | FallbackRender | undefined;
|
|
30
29
|
/** Called when the error boundary encounters an error */
|
|
31
|
-
onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;
|
|
30
|
+
onError?: ((error: unknown, componentStack: string | undefined, eventId: string) => void) | undefined;
|
|
32
31
|
/** Called on componentDidMount() */
|
|
33
32
|
onMount?: (() => void) | undefined;
|
|
34
33
|
/** Called if resetError() is called from the fallback render props function */
|
|
35
|
-
onReset?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
|
|
34
|
+
onReset?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;
|
|
36
35
|
/** Called on componentWillUnmount() */
|
|
37
|
-
onUnmount?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
|
|
36
|
+
onUnmount?: ((error: unknown, componentStack: string | null | undefined, eventId: string | null) => void) | undefined;
|
|
38
37
|
/** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */
|
|
39
38
|
beforeCapture?: ((scope: Scope, error: unknown, componentStack: string | undefined) => void) | undefined;
|
|
40
39
|
};
|
|
@@ -58,7 +57,7 @@ declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBou
|
|
|
58
57
|
private readonly _openFallbackReportDialog;
|
|
59
58
|
private _lastEventId?;
|
|
60
59
|
constructor(props: ErrorBoundaryProps);
|
|
61
|
-
componentDidCatch(error: unknown,
|
|
60
|
+
componentDidCatch(error: unknown, errorInfo: React.ErrorInfo): void;
|
|
62
61
|
componentDidMount(): void;
|
|
63
62
|
componentWillUnmount(): void;
|
|
64
63
|
resetErrorBoundary: () => void;
|
package/types-ts3.8/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/browser';
|
|
2
2
|
export { init } from './sdk';
|
|
3
|
+
export { reactErrorHandler } from './error';
|
|
3
4
|
export { Profiler, withProfiler, useProfiler } from './profiler';
|
|
4
5
|
export { ErrorBoundaryProps, FallbackRender } from './errorboundary';
|
|
5
6
|
export { ErrorBoundary, withErrorBoundary } from './errorboundary';
|