@sentry/react-native 5.23.0-alpha.1 → 5.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -48
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +1 -54
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +0 -10
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +0 -10
- package/dist/js/NativeRNSentry.d.ts +0 -2
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/client.d.ts +0 -8
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +3 -19
- package/dist/js/client.js.map +1 -1
- package/dist/js/index.d.ts +5 -3
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +5 -3
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/debugsymbolicator.d.ts +8 -60
- package/dist/js/integrations/debugsymbolicator.d.ts.map +1 -1
- package/dist/js/integrations/debugsymbolicator.js +137 -209
- package/dist/js/integrations/debugsymbolicator.js.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.d.ts +18 -0
- package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -0
- package/dist/js/integrations/debugsymbolicatorutils.js +70 -0
- package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -0
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +24 -49
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/devicecontext.d.ts +8 -15
- package/dist/js/integrations/devicecontext.d.ts.map +1 -1
- package/dist/js/integrations/devicecontext.js +74 -74
- package/dist/js/integrations/devicecontext.js.map +1 -1
- package/dist/js/integrations/eventorigin.d.ts +8 -15
- package/dist/js/integrations/eventorigin.d.ts.map +1 -1
- package/dist/js/integrations/eventorigin.js +17 -17
- package/dist/js/integrations/eventorigin.js.map +1 -1
- package/dist/js/integrations/expocontext.d.ts +8 -15
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +28 -32
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/exports.d.ts +16 -0
- package/dist/js/integrations/exports.d.ts.map +1 -0
- package/dist/js/integrations/exports.js +16 -0
- package/dist/js/integrations/exports.js.map +1 -0
- package/dist/js/integrations/index.d.ts +4 -1
- package/dist/js/integrations/index.d.ts.map +1 -1
- package/dist/js/integrations/index.js +5 -1
- package/dist/js/integrations/index.js.map +1 -1
- package/dist/js/integrations/modulesloader.d.ts +8 -15
- package/dist/js/integrations/modulesloader.d.ts.map +1 -1
- package/dist/js/integrations/modulesloader.js +34 -31
- package/dist/js/integrations/modulesloader.js.map +1 -1
- package/dist/js/integrations/nativelinkederrors.d.ts +8 -51
- package/dist/js/integrations/nativelinkederrors.d.ts.map +1 -1
- package/dist/js/integrations/nativelinkederrors.js +112 -124
- package/dist/js/integrations/nativelinkederrors.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts +8 -54
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +109 -199
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlersutils.d.ts +27 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.d.ts.map +1 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.js +77 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.js.map +1 -0
- package/dist/js/integrations/reactnativeinfo.d.ts +8 -15
- package/dist/js/integrations/reactnativeinfo.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeinfo.js +51 -51
- package/dist/js/integrations/reactnativeinfo.js.map +1 -1
- package/dist/js/integrations/release.d.ts +8 -15
- package/dist/js/integrations/release.d.ts.map +1 -1
- package/dist/js/integrations/release.js +55 -57
- package/dist/js/integrations/release.js.map +1 -1
- package/dist/js/integrations/rewriteframes.js +2 -2
- package/dist/js/integrations/rewriteframes.js.map +1 -1
- package/dist/js/integrations/screenshot.d.ts +8 -23
- package/dist/js/integrations/screenshot.d.ts.map +1 -1
- package/dist/js/integrations/screenshot.js +31 -47
- package/dist/js/integrations/screenshot.js.map +1 -1
- package/dist/js/integrations/sdkinfo.d.ts +8 -16
- package/dist/js/integrations/sdkinfo.d.ts.map +1 -1
- package/dist/js/integrations/sdkinfo.js +54 -41
- package/dist/js/integrations/sdkinfo.js.map +1 -1
- package/dist/js/integrations/spotlight.d.ts +10 -2
- package/dist/js/integrations/spotlight.d.ts.map +1 -1
- package/dist/js/integrations/spotlight.js +14 -9
- package/dist/js/integrations/spotlight.js.map +1 -1
- package/dist/js/integrations/viewhierarchy.d.ts +8 -18
- package/dist/js/integrations/viewhierarchy.d.ts.map +1 -1
- package/dist/js/integrations/viewhierarchy.js +46 -43
- package/dist/js/integrations/viewhierarchy.js.map +1 -1
- package/dist/js/options.d.ts +2 -24
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/profiling/integration.d.ts +8 -32
- package/dist/js/profiling/integration.d.ts.map +1 -1
- package/dist/js/profiling/integration.js +120 -119
- package/dist/js/profiling/integration.js.map +1 -1
- package/dist/js/tracing/nativeframes.d.ts +0 -4
- package/dist/js/tracing/nativeframes.d.ts.map +1 -1
- package/dist/js/tracing/nativeframes.js +14 -14
- package/dist/js/tracing/nativeframes.js.map +1 -1
- package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
- package/dist/js/tracing/reactnativetracing.js +9 -2
- package/dist/js/tracing/reactnativetracing.js.map +1 -1
- package/dist/js/tracing/timetodisplay.d.ts +1 -1
- package/dist/js/tracing/timetodisplay.d.ts.map +1 -1
- package/dist/js/tracing/timetodisplay.js +15 -7
- package/dist/js/tracing/timetodisplay.js.map +1 -1
- package/dist/js/utils/environment.d.ts +0 -4
- package/dist/js/utils/environment.d.ts.map +1 -1
- package/dist/js/utils/environment.js +0 -8
- package/dist/js/utils/environment.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +1 -7
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +0 -24
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +3 -73
- package/ios/RNSentryBreadcrumb.h +9 -0
- package/ios/RNSentryBreadcrumb.m +33 -0
- package/ios/RNSentryOnDrawReporter.h +23 -0
- package/ios/RNSentryOnDrawReporter.m +2 -17
- package/package.json +1 -9
- package/src/js/NativeRNSentry.ts +0 -2
- package/ts3.8/dist/js/NativeRNSentry.d.ts +0 -2
- package/ts3.8/dist/js/client.d.ts +0 -8
- package/ts3.8/dist/js/index.d.ts +5 -3
- package/ts3.8/dist/js/integrations/debugsymbolicator.d.ts +8 -60
- package/ts3.8/dist/js/integrations/debugsymbolicatorutils.d.ts +18 -0
- package/ts3.8/dist/js/integrations/devicecontext.d.ts +8 -15
- package/ts3.8/dist/js/integrations/eventorigin.d.ts +8 -15
- package/ts3.8/dist/js/integrations/expocontext.d.ts +8 -15
- package/ts3.8/dist/js/integrations/exports.d.ts +16 -0
- package/ts3.8/dist/js/integrations/index.d.ts +4 -1
- package/ts3.8/dist/js/integrations/modulesloader.d.ts +8 -15
- package/ts3.8/dist/js/integrations/nativelinkederrors.d.ts +8 -51
- package/ts3.8/dist/js/integrations/reactnativeerrorhandlers.d.ts +8 -54
- package/ts3.8/dist/js/integrations/reactnativeerrorhandlersutils.d.ts +27 -0
- package/ts3.8/dist/js/integrations/reactnativeinfo.d.ts +8 -15
- package/ts3.8/dist/js/integrations/release.d.ts +8 -15
- package/ts3.8/dist/js/integrations/screenshot.d.ts +8 -23
- package/ts3.8/dist/js/integrations/sdkinfo.d.ts +8 -16
- package/ts3.8/dist/js/integrations/spotlight.d.ts +10 -2
- package/ts3.8/dist/js/integrations/viewhierarchy.d.ts +8 -18
- package/ts3.8/dist/js/options.d.ts +2 -24
- package/ts3.8/dist/js/profiling/integration.d.ts +8 -32
- package/ts3.8/dist/js/tracing/nativeframes.d.ts +0 -4
- package/ts3.8/dist/js/tracing/timetodisplay.d.ts +1 -1
- package/ts3.8/dist/js/utils/environment.d.ts +0 -4
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +1 -7
- package/dist/js/integrations/mobilereplay.d.ts +0 -36
- package/dist/js/integrations/mobilereplay.d.ts.map +0 -1
- package/dist/js/integrations/mobilereplay.js +0 -97
- package/dist/js/integrations/mobilereplay.js.map +0 -1
- package/dist/js/utils/clientutils.d.ts +0 -8
- package/dist/js/utils/clientutils.d.ts.map +0 -1
- package/dist/js/utils/clientutils.js +0 -7
- package/dist/js/utils/clientutils.js.map +0 -1
- package/ts3.8/dist/js/integrations/mobilereplay.d.ts +0 -36
- package/ts3.8/dist/js/utils/clientutils.d.ts +0 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Integration } from '@sentry/types';
|
|
1
|
+
import type { Integration, IntegrationClass, IntegrationFnResult } from '@sentry/types';
|
|
2
2
|
/** ReactNativeErrorHandlers Options */
|
|
3
3
|
interface ReactNativeErrorHandlersOptions {
|
|
4
4
|
onerror: boolean;
|
|
@@ -6,58 +6,12 @@ interface ReactNativeErrorHandlersOptions {
|
|
|
6
6
|
patchGlobalPromise: boolean;
|
|
7
7
|
}
|
|
8
8
|
/** ReactNativeErrorHandlers Integration */
|
|
9
|
-
export declare
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*/
|
|
17
|
-
name: string;
|
|
18
|
-
/** ReactNativeOptions */
|
|
19
|
-
private readonly _options;
|
|
20
|
-
/** Constructor */
|
|
21
|
-
constructor(options?: Partial<ReactNativeErrorHandlersOptions>);
|
|
22
|
-
/**
|
|
23
|
-
* @inheritDoc
|
|
24
|
-
*/
|
|
25
|
-
setupOnce(): void;
|
|
26
|
-
/**
|
|
27
|
-
* Handle Promises
|
|
28
|
-
*/
|
|
29
|
-
private _handleUnhandledRejections;
|
|
30
|
-
/**
|
|
31
|
-
* Polyfill the global promise instance with one we can be sure that we can attach the tracking to.
|
|
32
|
-
*
|
|
33
|
-
* In newer RN versions >=0.63, the global promise is not the same reference as the one imported from the promise library.
|
|
34
|
-
* This is due to a version mismatch between promise versions.
|
|
35
|
-
* Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,
|
|
36
|
-
* - Using a package resolution requires the you to manually troubleshoot.
|
|
37
|
-
* - The package resolution fix no longer works with 0.67 on iOS Hermes.
|
|
38
|
-
*/
|
|
39
|
-
private _polyfillPromise;
|
|
40
|
-
/**
|
|
41
|
-
* Single source of truth for the Promise implementation we want to use.
|
|
42
|
-
* This is important for verifying that the rejected promise tracing will work as expected.
|
|
43
|
-
*/
|
|
44
|
-
private _getPromisePolyfill;
|
|
45
|
-
/**
|
|
46
|
-
* Attach the unhandled rejection handler
|
|
47
|
-
*/
|
|
48
|
-
private _attachUnhandledRejectionHandler;
|
|
49
|
-
/**
|
|
50
|
-
* Checks if the promise is the same one or not, if not it will warn the user
|
|
51
|
-
*/
|
|
52
|
-
private _checkPromiseAndWarn;
|
|
53
|
-
/**
|
|
54
|
-
* Handle errors
|
|
55
|
-
*/
|
|
56
|
-
private _handleOnError;
|
|
57
|
-
/**
|
|
58
|
-
* Loads and returns rejection tracking module
|
|
59
|
-
*/
|
|
60
|
-
private _loadRejectionTracking;
|
|
61
|
-
}
|
|
9
|
+
export declare const reactNativeErrorHandlersIntegration: (options?: Partial<ReactNativeErrorHandlersOptions>) => IntegrationFnResult;
|
|
10
|
+
/**
|
|
11
|
+
* ReactNativeErrorHandlers Integration
|
|
12
|
+
*
|
|
13
|
+
* @deprecated Use `reactNativeErrorHandlersIntegration()` instead.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ReactNativeErrorHandlers: IntegrationClass<Integration> & (new (options?: Partial<ReactNativeErrorHandlersOptions>) => Integration);
|
|
62
16
|
export {};
|
|
63
17
|
//# sourceMappingURL=reactnativeerrorhandlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativeerrorhandlers.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"reactnativeerrorhandlers.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAiB,MAAM,eAAe,CAAC;AASlH,uCAAuC;AACvC,UAAU,+BAA+B;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAOD,2CAA2C;AAC3C,eAAO,MAAM,mCAAmC,aACrC,QAAQ,+BAA+B,CAAC,KAChD,mBAWF,CAAC;AAEF;;;;GAIG;AAEH,eAAO,MAAM,wBAAwB,kDAIpB,QAAQ,+BAA+B,CAAC,KAAG,WAAW,CACtE,CAAC"}
|
|
@@ -1,216 +1,126 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
|
-
import {
|
|
2
|
+
import { captureException, convertIntegrationFnToClass, getClient, getCurrentScope } from '@sentry/core';
|
|
3
3
|
import { addExceptionMechanism, logger } from '@sentry/utils';
|
|
4
4
|
import { createSyntheticError, isErrorLike } from '../utils/error';
|
|
5
|
-
import { ReactNativeLibraries } from '../utils/rnlibraries';
|
|
6
5
|
import { RN_GLOBAL_OBJ } from '../utils/worldwide';
|
|
6
|
+
import { checkPromiseAndWarn, polyfillPromise, requireRejectionTracking } from './reactnativeerrorhandlersutils';
|
|
7
|
+
const INTEGRATION_NAME = 'ReactNativeErrorHandlers';
|
|
7
8
|
/** ReactNativeErrorHandlers Integration */
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
export const reactNativeErrorHandlersIntegration = (options = {}) => {
|
|
10
|
+
return {
|
|
11
|
+
name: INTEGRATION_NAME,
|
|
12
|
+
setupOnce: () => setup(Object.assign({ onerror: true, onunhandledrejection: true, patchGlobalPromise: true }, options)),
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* ReactNativeErrorHandlers Integration
|
|
17
|
+
*
|
|
18
|
+
* @deprecated Use `reactNativeErrorHandlersIntegration()` instead.
|
|
19
|
+
*/
|
|
20
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
21
|
+
export const ReactNativeErrorHandlers = convertIntegrationFnToClass(INTEGRATION_NAME, reactNativeErrorHandlersIntegration);
|
|
22
|
+
function setup(options) {
|
|
23
|
+
options.onunhandledrejection && setupUnhandledRejectionsTracking(options.patchGlobalPromise);
|
|
24
|
+
options.onerror && setupErrorUtilsGlobalHandler();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Setup unhandled promise rejection tracking
|
|
28
|
+
*/
|
|
29
|
+
function setupUnhandledRejectionsTracking(patchGlobalPromise) {
|
|
30
|
+
if (patchGlobalPromise) {
|
|
31
|
+
polyfillPromise();
|
|
16
32
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
attachUnhandledRejectionHandler();
|
|
34
|
+
checkPromiseAndWarn();
|
|
35
|
+
}
|
|
36
|
+
function attachUnhandledRejectionHandler() {
|
|
37
|
+
const tracking = requireRejectionTracking();
|
|
38
|
+
const promiseRejectionTrackingOptions = {
|
|
39
|
+
onUnhandled: (id, rejection = {}) => {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.warn(`Possible Unhandled Promise Rejection (id: ${id}):\n${rejection}`);
|
|
42
|
+
},
|
|
43
|
+
onHandled: id => {
|
|
44
|
+
// eslint-disable-next-line no-console
|
|
45
|
+
console.warn(`Promise Rejection Handled (id: ${id})\n` +
|
|
46
|
+
'This means you can ignore any previous messages of the form ' +
|
|
47
|
+
`"Possible Unhandled Promise Rejection (id: ${id}):"`);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
tracking.enable({
|
|
51
|
+
allRejections: true,
|
|
52
|
+
onUnhandled: (id, error) => {
|
|
53
|
+
if (__DEV__) {
|
|
54
|
+
promiseRejectionTrackingOptions.onUnhandled(id, error);
|
|
55
|
+
}
|
|
56
|
+
captureException(error, {
|
|
57
|
+
data: { id },
|
|
58
|
+
originalException: error,
|
|
59
|
+
syntheticException: isErrorLike(error) ? undefined : createSyntheticError(),
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
onHandled: (id) => {
|
|
63
|
+
promiseRejectionTrackingOptions.onHandled(id);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function setupErrorUtilsGlobalHandler() {
|
|
68
|
+
let handlingFatal = false;
|
|
69
|
+
const errorUtils = RN_GLOBAL_OBJ.ErrorUtils;
|
|
70
|
+
if (!errorUtils) {
|
|
71
|
+
logger.warn('ErrorUtils not found. Can be caused by different environment for example react-native-web.');
|
|
72
|
+
return;
|
|
23
73
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
74
|
+
const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler();
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
errorUtils.setGlobalHandler((error, isFatal) => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
// We want to handle fatals, but only in production mode.
|
|
78
|
+
const shouldHandleFatal = isFatal && !__DEV__;
|
|
79
|
+
if (shouldHandleFatal) {
|
|
80
|
+
if (handlingFatal) {
|
|
81
|
+
logger.log('Encountered multiple fatals in a row. The latest:', error);
|
|
82
|
+
return;
|
|
31
83
|
}
|
|
32
|
-
|
|
33
|
-
this._checkPromiseAndWarn();
|
|
84
|
+
handlingFatal = true;
|
|
34
85
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* This is due to a version mismatch between promise versions.
|
|
41
|
-
* Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,
|
|
42
|
-
* - Using a package resolution requires the you to manually troubleshoot.
|
|
43
|
-
* - The package resolution fix no longer works with 0.67 on iOS Hermes.
|
|
44
|
-
*/
|
|
45
|
-
_polyfillPromise() {
|
|
46
|
-
if (!ReactNativeLibraries.Utilities) {
|
|
47
|
-
logger.warn('Could not polyfill Promise. React Native Libraries Utilities not found.');
|
|
86
|
+
const client = getClient();
|
|
87
|
+
if (!client) {
|
|
88
|
+
logger.error('Sentry client is missing, the error event might be lost.', error);
|
|
89
|
+
// If there is no client something is fishy, anyway we call the default handler
|
|
90
|
+
defaultHandler(error, isFatal);
|
|
48
91
|
return;
|
|
49
92
|
}
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
require('promise/setimmediate/done');
|
|
54
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
55
|
-
require('promise/setimmediate/finally');
|
|
56
|
-
ReactNativeLibraries.Utilities.polyfillGlobal('Promise', () => Promise);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Single source of truth for the Promise implementation we want to use.
|
|
60
|
-
* This is important for verifying that the rejected promise tracing will work as expected.
|
|
61
|
-
*/
|
|
62
|
-
_getPromisePolyfill() {
|
|
63
|
-
/* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */
|
|
64
|
-
// Below, we follow the exact way React Native initializes its promise library, and we globally replace it.
|
|
65
|
-
return require('promise/setimmediate/es6-extensions');
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Attach the unhandled rejection handler
|
|
69
|
-
*/
|
|
70
|
-
_attachUnhandledRejectionHandler() {
|
|
71
|
-
const tracking = this._loadRejectionTracking();
|
|
72
|
-
const promiseRejectionTrackingOptions = {
|
|
73
|
-
onUnhandled: (id, rejection = {}) => {
|
|
74
|
-
// eslint-disable-next-line no-console
|
|
75
|
-
console.warn(`Possible Unhandled Promise Rejection (id: ${id}):\n${rejection}`);
|
|
76
|
-
},
|
|
77
|
-
onHandled: id => {
|
|
78
|
-
// eslint-disable-next-line no-console
|
|
79
|
-
console.warn(`Promise Rejection Handled (id: ${id})\n` +
|
|
80
|
-
'This means you can ignore any previous messages of the form ' +
|
|
81
|
-
`"Possible Unhandled Promise Rejection (id: ${id}):"`);
|
|
82
|
-
},
|
|
93
|
+
const hint = {
|
|
94
|
+
originalException: error,
|
|
95
|
+
attachments: getCurrentScope().getScopeData().attachments,
|
|
83
96
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
data: { id },
|
|
92
|
-
originalException: error,
|
|
93
|
-
syntheticException: isErrorLike(error) ? undefined : createSyntheticError(),
|
|
94
|
-
});
|
|
95
|
-
},
|
|
96
|
-
onHandled: (id) => {
|
|
97
|
-
promiseRejectionTrackingOptions.onHandled(id);
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Checks if the promise is the same one or not, if not it will warn the user
|
|
103
|
-
*/
|
|
104
|
-
_checkPromiseAndWarn() {
|
|
105
|
-
try {
|
|
106
|
-
// `promise` package is a dependency of react-native, therefore it is always available.
|
|
107
|
-
// but it is possible that the user has installed a different version of promise
|
|
108
|
-
// or dependency that uses a different version.
|
|
109
|
-
// We have to check if the React Native Promise and the `promise` package Promise are using the same reference.
|
|
110
|
-
// If they are not, likely there are multiple versions of the `promise` package installed.
|
|
111
|
-
const ReactNativePromise = ReactNativeLibraries.Promise;
|
|
112
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
|
|
113
|
-
const PromisePackagePromise = require('promise/setimmediate/es6-extensions');
|
|
114
|
-
const UsedPromisePolyfill = this._getPromisePolyfill();
|
|
115
|
-
if (ReactNativePromise !== PromisePackagePromise) {
|
|
116
|
-
logger.warn('You appear to have multiple versions of the "promise" package installed. ' +
|
|
117
|
-
'This may cause unexpected behavior like undefined `Promise.allSettled`. ' +
|
|
118
|
-
'Please install the `promise` package manually using the exact version as the React Native package. ' +
|
|
119
|
-
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
120
|
-
}
|
|
121
|
-
// This only make sense if the user disabled the integration Polyfill
|
|
122
|
-
if (UsedPromisePolyfill !== RN_GLOBAL_OBJ.Promise) {
|
|
123
|
-
logger.warn('Unhandled promise rejections will not be caught by Sentry. ' +
|
|
124
|
-
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
logger.log('Unhandled promise rejections will be caught by Sentry.');
|
|
128
|
-
}
|
|
97
|
+
const event = yield client.eventFromException(error, hint);
|
|
98
|
+
if (isFatal) {
|
|
99
|
+
event.level = 'fatal';
|
|
100
|
+
addExceptionMechanism(event, {
|
|
101
|
+
handled: false,
|
|
102
|
+
type: 'onerror',
|
|
103
|
+
});
|
|
129
104
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
105
|
+
else {
|
|
106
|
+
event.level = 'error';
|
|
107
|
+
addExceptionMechanism(event, {
|
|
108
|
+
handled: true,
|
|
109
|
+
type: 'generic',
|
|
110
|
+
});
|
|
134
111
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
let handlingFatal = false;
|
|
142
|
-
const errorUtils = RN_GLOBAL_OBJ.ErrorUtils;
|
|
143
|
-
if (!errorUtils) {
|
|
144
|
-
logger.warn('ErrorUtils not found. Can be caused by different environment for example react-native-web.');
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler();
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
149
|
-
errorUtils.setGlobalHandler((error, isFatal) => __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
// We want to handle fatals, but only in production mode.
|
|
151
|
-
const shouldHandleFatal = isFatal && !__DEV__;
|
|
152
|
-
if (shouldHandleFatal) {
|
|
153
|
-
if (handlingFatal) {
|
|
154
|
-
logger.log('Encountered multiple fatals in a row. The latest:', error);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
handlingFatal = true;
|
|
158
|
-
}
|
|
159
|
-
const currentHub = getCurrentHub();
|
|
160
|
-
const client = currentHub.getClient();
|
|
161
|
-
const scope = currentHub.getScope();
|
|
162
|
-
if (!client) {
|
|
163
|
-
logger.error('Sentry client is missing, the error event might be lost.', error);
|
|
164
|
-
// If there is no client something is fishy, anyway we call the default handler
|
|
165
|
-
defaultHandler(error, isFatal);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const options = client.getOptions();
|
|
169
|
-
const hint = {
|
|
170
|
-
originalException: error,
|
|
171
|
-
attachments: scope === null || scope === void 0 ? void 0 : scope.getAttachments(),
|
|
172
|
-
};
|
|
173
|
-
const event = yield client.eventFromException(error, hint);
|
|
174
|
-
if (isFatal) {
|
|
175
|
-
event.level = 'fatal';
|
|
176
|
-
addExceptionMechanism(event, {
|
|
177
|
-
handled: false,
|
|
178
|
-
type: 'onerror',
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
event.level = 'error';
|
|
183
|
-
addExceptionMechanism(event, {
|
|
184
|
-
handled: true,
|
|
185
|
-
type: 'generic',
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
currentHub.captureEvent(event, hint);
|
|
189
|
-
if (!__DEV__) {
|
|
190
|
-
void client.flush(options.shutdownTimeout || 2000).then(() => {
|
|
191
|
-
defaultHandler(error, isFatal);
|
|
192
|
-
}, (reason) => {
|
|
193
|
-
logger.error('[ReactNativeErrorHandlers] Error while flushing the event cache after uncaught error.', reason);
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
// If in dev, we call the default handler anyway and hope the error will be sent
|
|
198
|
-
// Just for a better dev experience
|
|
199
|
-
defaultHandler(error, isFatal);
|
|
200
|
-
}
|
|
201
|
-
}));
|
|
112
|
+
client.captureEvent(event, hint);
|
|
113
|
+
if (__DEV__) {
|
|
114
|
+
// If in dev, we call the default handler anyway and hope the error will be sent
|
|
115
|
+
// Just for a better dev experience
|
|
116
|
+
defaultHandler(error, isFatal);
|
|
117
|
+
return;
|
|
202
118
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return require('promise/setimmediate/rejection-tracking');
|
|
210
|
-
}
|
|
119
|
+
void client.flush(client.getOptions().shutdownTimeout || 2000).then(() => {
|
|
120
|
+
defaultHandler(error, isFatal);
|
|
121
|
+
}, (reason) => {
|
|
122
|
+
logger.error('[ReactNativeErrorHandlers] Error while flushing the event cache after uncaught error.', reason);
|
|
123
|
+
});
|
|
124
|
+
}));
|
|
211
125
|
}
|
|
212
|
-
/**
|
|
213
|
-
* @inheritDoc
|
|
214
|
-
*/
|
|
215
|
-
ReactNativeErrorHandlers.id = 'ReactNativeErrorHandlers';
|
|
216
126
|
//# sourceMappingURL=reactnativeerrorhandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativeerrorhandlers.js","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCurrentHub } from '@sentry/core';\nimport type { EventHint, Integration } from '@sentry/types';\nimport { addExceptionMechanism, logger } from '@sentry/utils';\n\nimport type { ReactNativeClient } from '../client';\nimport { createSyntheticError, isErrorLike } from '../utils/error';\nimport { ReactNativeLibraries } from '../utils/rnlibraries';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\n\n/** ReactNativeErrorHandlers Options */\ninterface ReactNativeErrorHandlersOptions {\n onerror: boolean;\n onunhandledrejection: boolean;\n patchGlobalPromise: boolean;\n}\n\ninterface PromiseRejectionTrackingOptions {\n onUnhandled: (id: string, error: unknown) => void;\n onHandled: (id: string) => void;\n}\n\n/** ReactNativeErrorHandlers Integration */\nexport class ReactNativeErrorHandlers implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'ReactNativeErrorHandlers';\n\n /**\n * @inheritDoc\n */\n public name: string = ReactNativeErrorHandlers.id;\n\n /** ReactNativeOptions */\n private readonly _options: ReactNativeErrorHandlersOptions;\n\n /** Constructor */\n public constructor(options?: Partial<ReactNativeErrorHandlersOptions>) {\n this._options = {\n onerror: true,\n onunhandledrejection: true,\n patchGlobalPromise: true,\n ...options,\n };\n }\n\n /**\n * @inheritDoc\n */\n public setupOnce(): void {\n this._handleUnhandledRejections();\n this._handleOnError();\n }\n\n /**\n * Handle Promises\n */\n private _handleUnhandledRejections(): void {\n if (this._options.onunhandledrejection) {\n if (this._options.patchGlobalPromise) {\n this._polyfillPromise();\n }\n\n this._attachUnhandledRejectionHandler();\n this._checkPromiseAndWarn();\n }\n }\n /**\n * Polyfill the global promise instance with one we can be sure that we can attach the tracking to.\n *\n * In newer RN versions >=0.63, the global promise is not the same reference as the one imported from the promise library.\n * This is due to a version mismatch between promise versions.\n * Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,\n * - Using a package resolution requires the you to manually troubleshoot.\n * - The package resolution fix no longer works with 0.67 on iOS Hermes.\n */\n private _polyfillPromise(): void {\n if (!ReactNativeLibraries.Utilities) {\n logger.warn('Could not polyfill Promise. React Native Libraries Utilities not found.');\n return;\n }\n\n const Promise = this._getPromisePolyfill();\n\n // As of RN 0.67 only done and finally are used\n // eslint-disable-next-line import/no-extraneous-dependencies\n require('promise/setimmediate/done');\n // eslint-disable-next-line import/no-extraneous-dependencies\n require('promise/setimmediate/finally');\n\n ReactNativeLibraries.Utilities.polyfillGlobal('Promise', () => Promise);\n }\n\n /**\n * Single source of truth for the Promise implementation we want to use.\n * This is important for verifying that the rejected promise tracing will work as expected.\n */\n private _getPromisePolyfill(): unknown {\n /* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\n // Below, we follow the exact way React Native initializes its promise library, and we globally replace it.\n return require('promise/setimmediate/es6-extensions');\n }\n\n /**\n * Attach the unhandled rejection handler\n */\n private _attachUnhandledRejectionHandler(): void {\n const tracking = this._loadRejectionTracking();\n\n const promiseRejectionTrackingOptions: PromiseRejectionTrackingOptions = {\n onUnhandled: (id, rejection = {}) => {\n // eslint-disable-next-line no-console\n console.warn(`Possible Unhandled Promise Rejection (id: ${id}):\\n${rejection}`);\n },\n onHandled: id => {\n // eslint-disable-next-line no-console\n console.warn(\n `Promise Rejection Handled (id: ${id})\\n` +\n 'This means you can ignore any previous messages of the form ' +\n `\"Possible Unhandled Promise Rejection (id: ${id}):\"`,\n );\n },\n };\n\n tracking.enable({\n allRejections: true,\n onUnhandled: (id: string, error: unknown) => {\n if (__DEV__) {\n promiseRejectionTrackingOptions.onUnhandled(id, error);\n }\n\n getCurrentHub().captureException(error, {\n data: { id },\n originalException: error,\n syntheticException: isErrorLike(error) ? undefined : createSyntheticError(),\n });\n },\n onHandled: (id: string) => {\n promiseRejectionTrackingOptions.onHandled(id);\n },\n });\n }\n /**\n * Checks if the promise is the same one or not, if not it will warn the user\n */\n private _checkPromiseAndWarn(): void {\n try {\n // `promise` package is a dependency of react-native, therefore it is always available.\n // but it is possible that the user has installed a different version of promise\n // or dependency that uses a different version.\n // We have to check if the React Native Promise and the `promise` package Promise are using the same reference.\n // If they are not, likely there are multiple versions of the `promise` package installed.\n const ReactNativePromise = ReactNativeLibraries.Promise;\n // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n const PromisePackagePromise = require('promise/setimmediate/es6-extensions');\n const UsedPromisePolyfill = this._getPromisePolyfill();\n\n if (ReactNativePromise !== PromisePackagePromise) {\n logger.warn(\n 'You appear to have multiple versions of the \"promise\" package installed. ' +\n 'This may cause unexpected behavior like undefined `Promise.allSettled`. ' +\n 'Please install the `promise` package manually using the exact version as the React Native package. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n }\n\n // This only make sense if the user disabled the integration Polyfill\n if (UsedPromisePolyfill !== RN_GLOBAL_OBJ.Promise) {\n logger.warn(\n 'Unhandled promise rejections will not be caught by Sentry. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n } else {\n logger.log('Unhandled promise rejections will be caught by Sentry.');\n }\n } catch (e) {\n // Do Nothing\n logger.warn(\n 'Unhandled promise rejections will not be caught by Sentry. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n }\n }\n /**\n * Handle errors\n */\n private _handleOnError(): void {\n if (this._options.onerror) {\n let handlingFatal = false;\n\n const errorUtils = RN_GLOBAL_OBJ.ErrorUtils;\n if (!errorUtils) {\n logger.warn('ErrorUtils not found. Can be caused by different environment for example react-native-web.');\n return;\n }\n\n const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errorUtils.setGlobalHandler(async (error: any, isFatal?: boolean) => {\n // We want to handle fatals, but only in production mode.\n const shouldHandleFatal = isFatal && !__DEV__;\n if (shouldHandleFatal) {\n if (handlingFatal) {\n logger.log('Encountered multiple fatals in a row. The latest:', error);\n return;\n }\n handlingFatal = true;\n }\n\n const currentHub = getCurrentHub();\n const client = currentHub.getClient<ReactNativeClient>();\n const scope = currentHub.getScope();\n\n if (!client) {\n logger.error('Sentry client is missing, the error event might be lost.', error);\n\n // If there is no client something is fishy, anyway we call the default handler\n defaultHandler(error, isFatal);\n\n return;\n }\n\n const options = client.getOptions();\n\n const hint: EventHint = {\n originalException: error,\n attachments: scope?.getAttachments(),\n };\n const event = await client.eventFromException(error, hint);\n\n if (isFatal) {\n event.level = 'fatal';\n\n addExceptionMechanism(event, {\n handled: false,\n type: 'onerror',\n });\n } else {\n event.level = 'error';\n\n addExceptionMechanism(event, {\n handled: true,\n type: 'generic',\n });\n }\n\n currentHub.captureEvent(event, hint);\n\n if (!__DEV__) {\n void client.flush(options.shutdownTimeout || 2000).then(\n () => {\n defaultHandler(error, isFatal);\n },\n (reason: unknown) => {\n logger.error(\n '[ReactNativeErrorHandlers] Error while flushing the event cache after uncaught error.',\n reason,\n );\n },\n );\n } else {\n // If in dev, we call the default handler anyway and hope the error will be sent\n // Just for a better dev experience\n defaultHandler(error, isFatal);\n }\n });\n }\n }\n\n /**\n * Loads and returns rejection tracking module\n */\n private _loadRejectionTracking(): {\n disable: () => void;\n enable: (arg: unknown) => void;\n } {\n // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n return require('promise/setimmediate/rejection-tracking');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reactnativeerrorhandlers.js","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"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","sourcesContent":["import { captureException, convertIntegrationFnToClass, getClient, getCurrentScope } from '@sentry/core';\nimport type { EventHint, Integration, IntegrationClass, IntegrationFnResult, SeverityLevel } from '@sentry/types';\nimport { addExceptionMechanism, logger } from '@sentry/utils';\n\nimport { createSyntheticError, isErrorLike } from '../utils/error';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\nimport { checkPromiseAndWarn, polyfillPromise, requireRejectionTracking } from './reactnativeerrorhandlersutils';\n\nconst INTEGRATION_NAME = 'ReactNativeErrorHandlers';\n\n/** ReactNativeErrorHandlers Options */\ninterface ReactNativeErrorHandlersOptions {\n onerror: boolean;\n onunhandledrejection: boolean;\n patchGlobalPromise: boolean;\n}\n\ninterface PromiseRejectionTrackingOptions {\n onUnhandled: (id: string, error: unknown) => void;\n onHandled: (id: string) => void;\n}\n\n/** ReactNativeErrorHandlers Integration */\nexport const reactNativeErrorHandlersIntegration = (\n options: Partial<ReactNativeErrorHandlersOptions> = {},\n): IntegrationFnResult => {\n return {\n name: INTEGRATION_NAME,\n setupOnce: () =>\n setup({\n onerror: true,\n onunhandledrejection: true,\n patchGlobalPromise: true,\n ...options,\n }),\n };\n};\n\n/**\n * ReactNativeErrorHandlers Integration\n *\n * @deprecated Use `reactNativeErrorHandlersIntegration()` instead.\n */\n// eslint-disable-next-line deprecation/deprecation\nexport const ReactNativeErrorHandlers = convertIntegrationFnToClass(\n INTEGRATION_NAME,\n reactNativeErrorHandlersIntegration,\n) as IntegrationClass<Integration> & {\n new (options?: Partial<ReactNativeErrorHandlersOptions>): Integration;\n};\n\nfunction setup(options: ReactNativeErrorHandlersOptions): void {\n options.onunhandledrejection && setupUnhandledRejectionsTracking(options.patchGlobalPromise);\n options.onerror && setupErrorUtilsGlobalHandler();\n}\n\n/**\n * Setup unhandled promise rejection tracking\n */\nfunction setupUnhandledRejectionsTracking(patchGlobalPromise: boolean): void {\n if (patchGlobalPromise) {\n polyfillPromise();\n }\n\n attachUnhandledRejectionHandler();\n checkPromiseAndWarn();\n}\n\nfunction attachUnhandledRejectionHandler(): void {\n const tracking = requireRejectionTracking();\n\n const promiseRejectionTrackingOptions: PromiseRejectionTrackingOptions = {\n onUnhandled: (id, rejection = {}) => {\n // eslint-disable-next-line no-console\n console.warn(`Possible Unhandled Promise Rejection (id: ${id}):\\n${rejection}`);\n },\n onHandled: id => {\n // eslint-disable-next-line no-console\n console.warn(\n `Promise Rejection Handled (id: ${id})\\n` +\n 'This means you can ignore any previous messages of the form ' +\n `\"Possible Unhandled Promise Rejection (id: ${id}):\"`,\n );\n },\n };\n\n tracking.enable({\n allRejections: true,\n onUnhandled: (id: string, error: unknown) => {\n if (__DEV__) {\n promiseRejectionTrackingOptions.onUnhandled(id, error);\n }\n\n captureException(error, {\n data: { id },\n originalException: error,\n syntheticException: isErrorLike(error) ? undefined : createSyntheticError(),\n });\n },\n onHandled: (id: string) => {\n promiseRejectionTrackingOptions.onHandled(id);\n },\n });\n}\n\nfunction setupErrorUtilsGlobalHandler(): void {\n let handlingFatal = false;\n\n const errorUtils = RN_GLOBAL_OBJ.ErrorUtils;\n if (!errorUtils) {\n logger.warn('ErrorUtils not found. Can be caused by different environment for example react-native-web.');\n return;\n }\n\n const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errorUtils.setGlobalHandler(async (error: any, isFatal?: boolean) => {\n // We want to handle fatals, but only in production mode.\n const shouldHandleFatal = isFatal && !__DEV__;\n if (shouldHandleFatal) {\n if (handlingFatal) {\n logger.log('Encountered multiple fatals in a row. The latest:', error);\n return;\n }\n handlingFatal = true;\n }\n\n const client = getClient();\n\n if (!client) {\n logger.error('Sentry client is missing, the error event might be lost.', error);\n\n // If there is no client something is fishy, anyway we call the default handler\n defaultHandler(error, isFatal);\n\n return;\n }\n\n const hint: EventHint = {\n originalException: error,\n attachments: getCurrentScope().getScopeData().attachments,\n };\n const event = await client.eventFromException(error, hint);\n\n if (isFatal) {\n event.level = 'fatal' as SeverityLevel;\n\n addExceptionMechanism(event, {\n handled: false,\n type: 'onerror',\n });\n } else {\n event.level = 'error';\n\n addExceptionMechanism(event, {\n handled: true,\n type: 'generic',\n });\n }\n\n client.captureEvent(event, hint);\n\n if (__DEV__) {\n // If in dev, we call the default handler anyway and hope the error will be sent\n // Just for a better dev experience\n defaultHandler(error, isFatal);\n return;\n }\n\n void client.flush(client.getOptions().shutdownTimeout || 2000).then(\n () => {\n defaultHandler(error, isFatal);\n },\n (reason: unknown) => {\n logger.error('[ReactNativeErrorHandlers] Error while flushing the event cache after uncaught error.', reason);\n },\n );\n });\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polyfill the global promise instance with one we can be sure that we can attach the tracking to.
|
|
3
|
+
*
|
|
4
|
+
* In newer RN versions >=0.63, the global promise is not the same reference as the one imported from the promise library.
|
|
5
|
+
* This is due to a version mismatch between promise versions.
|
|
6
|
+
* Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,
|
|
7
|
+
* - Using a package resolution requires the you to manually troubleshoot.
|
|
8
|
+
* - The package resolution fix no longer works with 0.67 on iOS Hermes.
|
|
9
|
+
*/
|
|
10
|
+
export declare function polyfillPromise(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Single source of truth for the Promise implementation we want to use.
|
|
13
|
+
* This is important for verifying that the rejected promise tracing will work as expected.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getPromisePolyfill(): unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Lazy require the rejection tracking module
|
|
18
|
+
*/
|
|
19
|
+
export declare function requireRejectionTracking(): {
|
|
20
|
+
disable: () => void;
|
|
21
|
+
enable: (arg: unknown) => void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Checks if the promise is the same one or not, if not it will warn the user
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkPromiseAndWarn(): void;
|
|
27
|
+
//# sourceMappingURL=reactnativeerrorhandlersutils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactnativeerrorhandlersutils.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlersutils.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAetC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAChC,CAGA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAqC1C"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { logger } from '@sentry/utils';
|
|
2
|
+
import { ReactNativeLibraries } from '../utils/rnlibraries';
|
|
3
|
+
import { RN_GLOBAL_OBJ } from '../utils/worldwide';
|
|
4
|
+
/**
|
|
5
|
+
* Polyfill the global promise instance with one we can be sure that we can attach the tracking to.
|
|
6
|
+
*
|
|
7
|
+
* In newer RN versions >=0.63, the global promise is not the same reference as the one imported from the promise library.
|
|
8
|
+
* This is due to a version mismatch between promise versions.
|
|
9
|
+
* Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,
|
|
10
|
+
* - Using a package resolution requires the you to manually troubleshoot.
|
|
11
|
+
* - The package resolution fix no longer works with 0.67 on iOS Hermes.
|
|
12
|
+
*/
|
|
13
|
+
export function polyfillPromise() {
|
|
14
|
+
if (!ReactNativeLibraries.Utilities) {
|
|
15
|
+
logger.warn('Could not polyfill Promise. React Native Libraries Utilities not found.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const Promise = getPromisePolyfill();
|
|
19
|
+
// As of RN 0.67 only done and finally are used
|
|
20
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
21
|
+
require('promise/setimmediate/done');
|
|
22
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
23
|
+
require('promise/setimmediate/finally');
|
|
24
|
+
ReactNativeLibraries.Utilities.polyfillGlobal('Promise', () => Promise);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Single source of truth for the Promise implementation we want to use.
|
|
28
|
+
* This is important for verifying that the rejected promise tracing will work as expected.
|
|
29
|
+
*/
|
|
30
|
+
export function getPromisePolyfill() {
|
|
31
|
+
/* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */
|
|
32
|
+
// Below, we follow the exact way React Native initializes its promise library, and we globally replace it.
|
|
33
|
+
return require('promise/setimmediate/es6-extensions');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Lazy require the rejection tracking module
|
|
37
|
+
*/
|
|
38
|
+
export function requireRejectionTracking() {
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
|
|
40
|
+
return require('promise/setimmediate/rejection-tracking');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Checks if the promise is the same one or not, if not it will warn the user
|
|
44
|
+
*/
|
|
45
|
+
export function checkPromiseAndWarn() {
|
|
46
|
+
try {
|
|
47
|
+
// `promise` package is a dependency of react-native, therefore it is always available.
|
|
48
|
+
// but it is possible that the user has installed a different version of promise
|
|
49
|
+
// or dependency that uses a different version.
|
|
50
|
+
// We have to check if the React Native Promise and the `promise` package Promise are using the same reference.
|
|
51
|
+
// If they are not, likely there are multiple versions of the `promise` package installed.
|
|
52
|
+
const ReactNativePromise = ReactNativeLibraries.Promise;
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
|
|
54
|
+
const PromisePackagePromise = require('promise/setimmediate/es6-extensions');
|
|
55
|
+
const UsedPromisePolyfill = getPromisePolyfill();
|
|
56
|
+
if (ReactNativePromise !== PromisePackagePromise) {
|
|
57
|
+
logger.warn('You appear to have multiple versions of the "promise" package installed. ' +
|
|
58
|
+
'This may cause unexpected behavior like undefined `Promise.allSettled`. ' +
|
|
59
|
+
'Please install the `promise` package manually using the exact version as the React Native package. ' +
|
|
60
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
61
|
+
}
|
|
62
|
+
// This only make sense if the user disabled the integration Polyfill
|
|
63
|
+
if (UsedPromisePolyfill !== RN_GLOBAL_OBJ.Promise) {
|
|
64
|
+
logger.warn('Unhandled promise rejections will not be caught by Sentry. ' +
|
|
65
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
logger.log('Unhandled promise rejections will be caught by Sentry.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
// Do Nothing
|
|
73
|
+
logger.warn('Unhandled promise rejections will not be caught by Sentry. ' +
|
|
74
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=reactnativeerrorhandlersutils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactnativeerrorhandlersutils.js","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlersutils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE;QACnC,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QACvF,OAAO;KACR;IAED,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IAErC,+CAA+C;IAC/C,6DAA6D;IAC7D,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACrC,6DAA6D;IAC7D,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAExC,oBAAoB,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;AAC1E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,yFAAyF;IACzF,2GAA2G;IAC3G,OAAO,OAAO,CAAC,qCAAqC,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB;IAItC,gGAAgG;IAChG,OAAO,OAAO,CAAC,yCAAyC,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI;QACF,uFAAuF;QACvF,gFAAgF;QAChF,+CAA+C;QAC/C,+GAA+G;QAC/G,0FAA0F;QAC1F,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,OAAO,CAAC;QACxD,gGAAgG;QAChG,MAAM,qBAAqB,GAAG,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAC7E,MAAM,mBAAmB,GAAG,kBAAkB,EAAE,CAAC;QAEjD,IAAI,kBAAkB,KAAK,qBAAqB,EAAE;YAChD,MAAM,CAAC,IAAI,CACT,2EAA2E;gBACzE,0EAA0E;gBAC1E,qGAAqG;gBACrG,sFAAsF,CACzF,CAAC;SACH;QAED,qEAAqE;QACrE,IAAI,mBAAmB,KAAK,aAAa,CAAC,OAAO,EAAE;YACjD,MAAM,CAAC,IAAI,CACT,6DAA6D;gBAC3D,sFAAsF,CACzF,CAAC;SACH;aAAM;YACL,MAAM,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;SACtE;KACF;IAAC,OAAO,CAAC,EAAE;QACV,aAAa;QACb,MAAM,CAAC,IAAI,CACT,6DAA6D;YAC3D,sFAAsF,CACzF,CAAC;KACH;AACH,CAAC","sourcesContent":["import { logger } from '@sentry/utils';\n\nimport { ReactNativeLibraries } from '../utils/rnlibraries';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\n\n/**\n * Polyfill the global promise instance with one we can be sure that we can attach the tracking to.\n *\n * In newer RN versions >=0.63, the global promise is not the same reference as the one imported from the promise library.\n * This is due to a version mismatch between promise versions.\n * Originally we tried a solution where we would have you put a package resolution to ensure the promise instances match. However,\n * - Using a package resolution requires the you to manually troubleshoot.\n * - The package resolution fix no longer works with 0.67 on iOS Hermes.\n */\nexport function polyfillPromise(): void {\n if (!ReactNativeLibraries.Utilities) {\n logger.warn('Could not polyfill Promise. React Native Libraries Utilities not found.');\n return;\n }\n\n const Promise = getPromisePolyfill();\n\n // As of RN 0.67 only done and finally are used\n // eslint-disable-next-line import/no-extraneous-dependencies\n require('promise/setimmediate/done');\n // eslint-disable-next-line import/no-extraneous-dependencies\n require('promise/setimmediate/finally');\n\n ReactNativeLibraries.Utilities.polyfillGlobal('Promise', () => Promise);\n}\n\n/**\n * Single source of truth for the Promise implementation we want to use.\n * This is important for verifying that the rejected promise tracing will work as expected.\n */\nexport function getPromisePolyfill(): unknown {\n /* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\n // Below, we follow the exact way React Native initializes its promise library, and we globally replace it.\n return require('promise/setimmediate/es6-extensions');\n}\n\n/**\n * Lazy require the rejection tracking module\n */\nexport function requireRejectionTracking(): {\n disable: () => void;\n enable: (arg: unknown) => void;\n} {\n // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n return require('promise/setimmediate/rejection-tracking');\n}\n\n/**\n * Checks if the promise is the same one or not, if not it will warn the user\n */\nexport function checkPromiseAndWarn(): void {\n try {\n // `promise` package is a dependency of react-native, therefore it is always available.\n // but it is possible that the user has installed a different version of promise\n // or dependency that uses a different version.\n // We have to check if the React Native Promise and the `promise` package Promise are using the same reference.\n // If they are not, likely there are multiple versions of the `promise` package installed.\n const ReactNativePromise = ReactNativeLibraries.Promise;\n // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n const PromisePackagePromise = require('promise/setimmediate/es6-extensions');\n const UsedPromisePolyfill = getPromisePolyfill();\n\n if (ReactNativePromise !== PromisePackagePromise) {\n logger.warn(\n 'You appear to have multiple versions of the \"promise\" package installed. ' +\n 'This may cause unexpected behavior like undefined `Promise.allSettled`. ' +\n 'Please install the `promise` package manually using the exact version as the React Native package. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n }\n\n // This only make sense if the user disabled the integration Polyfill\n if (UsedPromisePolyfill !== RN_GLOBAL_OBJ.Promise) {\n logger.warn(\n 'Unhandled promise rejections will not be caught by Sentry. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n } else {\n logger.log('Unhandled promise rejections will be caught by Sentry.');\n }\n } catch (e) {\n // Do Nothing\n logger.warn(\n 'Unhandled promise rejections will not be caught by Sentry. ' +\n 'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.',\n );\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Context,
|
|
1
|
+
import type { Context, Integration, IntegrationClass, IntegrationFnResult } from '@sentry/types';
|
|
2
2
|
export interface ReactNativeContext extends Context {
|
|
3
3
|
js_engine?: string;
|
|
4
4
|
turbo_module: boolean;
|
|
@@ -12,18 +12,11 @@ export interface ReactNativeContext extends Context {
|
|
|
12
12
|
expo_sdk_version?: string;
|
|
13
13
|
}
|
|
14
14
|
/** Loads React Native context at runtime */
|
|
15
|
-
export declare
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
name: string;
|
|
24
|
-
/**
|
|
25
|
-
* @inheritDoc
|
|
26
|
-
*/
|
|
27
|
-
setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void): void;
|
|
28
|
-
}
|
|
15
|
+
export declare const reactNativeInfoIntegration: () => IntegrationFnResult;
|
|
16
|
+
/**
|
|
17
|
+
* Loads React Native context at runtime
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Use `reactNativeInfoIntegration()` instead.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ReactNativeInfo: IntegrationClass<Integration>;
|
|
29
22
|
//# sourceMappingURL=reactnativeinfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativeinfo.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeinfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactnativeinfo.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeinfo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAoB,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAgBnH,MAAM,WAAW,kBAAmB,SAAQ,OAAO;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,4CAA4C;AAC5C,eAAO,MAAM,0BAA0B,QAAO,mBAQ7C,CAAC;AAEF;;;;GAIG;AAEH,eAAO,MAAM,eAAe,+BAGM,CAAC"}
|