@sentry/react-native 5.7.1 → 5.8.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 +48 -0
- package/RNSentry.podspec +9 -4
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/MapConverter.java +134 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +103 -15
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +14 -2
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +13 -2
- package/dist/js/NativeRNSentry.d.ts +13 -4
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +1 -0
- package/dist/js/client.js.map +1 -1
- package/dist/js/integrations/devicecontext.js +5 -5
- package/dist/js/integrations/devicecontext.js.map +1 -1
- package/dist/js/integrations/index.d.ts +1 -0
- package/dist/js/integrations/index.d.ts.map +1 -1
- package/dist/js/integrations/index.js +1 -0
- package/dist/js/integrations/index.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts +5 -0
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +31 -6
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/integrations/rewriteframes.d.ts +2 -0
- package/dist/js/integrations/rewriteframes.d.ts.map +1 -1
- package/dist/js/integrations/rewriteframes.js +2 -2
- package/dist/js/integrations/rewriteframes.js.map +1 -1
- package/dist/js/integrations/sdkinfo.d.ts.map +1 -1
- package/dist/js/integrations/sdkinfo.js +1 -2
- package/dist/js/integrations/sdkinfo.js.map +1 -1
- package/dist/js/profiling/cache.d.ts +9 -0
- package/dist/js/profiling/cache.d.ts.map +1 -0
- package/dist/js/profiling/cache.js +3 -0
- package/dist/js/profiling/cache.js.map +1 -0
- package/dist/js/profiling/convertHermesProfile.d.ts +27 -0
- package/dist/js/profiling/convertHermesProfile.d.ts.map +1 -0
- package/dist/js/profiling/convertHermesProfile.js +141 -0
- package/dist/js/profiling/convertHermesProfile.js.map +1 -0
- package/dist/js/profiling/hermes.d.ts +52 -0
- package/dist/js/profiling/hermes.d.ts.map +1 -0
- package/dist/js/profiling/hermes.js +35 -0
- package/dist/js/profiling/hermes.js.map +1 -0
- package/dist/js/profiling/integration.d.ts +36 -0
- package/dist/js/profiling/integration.d.ts.map +1 -0
- package/dist/js/profiling/integration.js +151 -0
- package/dist/js/profiling/integration.js.map +1 -0
- package/dist/js/profiling/types.d.ts +5 -0
- package/dist/js/profiling/types.d.ts.map +1 -0
- package/dist/js/profiling/types.js +2 -0
- package/dist/js/profiling/types.js.map +1 -0
- package/dist/js/profiling/utils.d.ts +26 -0
- package/dist/js/profiling/utils.d.ts.map +1 -0
- package/dist/js/profiling/utils.js +135 -0
- package/dist/js/profiling/utils.js.map +1 -0
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +6 -1
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +4 -2
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +36 -27
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +75 -13
- package/package.json +15 -14
- package/src/js/NativeRNSentry.ts +7 -4
- package/ts3.8/dist/js/NativeRNSentry.d.ts +13 -4
- package/ts3.8/dist/js/integrations/index.d.ts +1 -0
- package/ts3.8/dist/js/integrations/reactnativeerrorhandlers.d.ts +5 -0
- package/ts3.8/dist/js/integrations/rewriteframes.d.ts +2 -0
- package/ts3.8/dist/js/profiling/cache.d.ts +9 -0
- package/ts3.8/dist/js/profiling/convertHermesProfile.d.ts +27 -0
- package/ts3.8/dist/js/profiling/hermes.d.ts +52 -0
- package/ts3.8/dist/js/profiling/integration.d.ts +36 -0
- package/ts3.8/dist/js/profiling/types.d.ts +5 -0
- package/ts3.8/dist/js/profiling/utils.d.ts +26 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devicecontext.js","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,uCAAuC;AACvC,MAAM,OAAO,aAAa;IAA1B;QAME;;WAEG;QACI,SAAI,GAAW,aAAa,CAAC,EAAE,CAAC;IA6EzC,CAAC;IA3EC;;OAEG;IACI,SAAS,CAAC,uBAA2D,EAAE,aAAwB;QACpG,uBAAuB,CAAC,CAAO,KAAY,EAAE,EAAE;;YAC7C,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YAC3D,IAAI,CAAC,IAAI,EAAE;gBACT,OAAO,KAAK,CAAC;aACd;YAED,IAAI,MAAM,GAAwC,IAAI,CAAC;YACvD,IAAI;gBACF,MAAM,GAAG,MAAM,MAAM,CAAC,yBAAyB,EAAE,CAAC;aACnD;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,EAAE,CAAC,CAAC;aAC9D;YAED,IAAI,CAAC,MAAM,EAAE;gBACX,OAAO,KAAK,CAAC;aACd;YAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,EAAE;gBAC7B,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;aACzB;YAED,IAAI,
|
|
1
|
+
{"version":3,"file":"devicecontext.js","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Event, EventProcessor, Hub, Integration } from '@sentry/types';\nimport { logger, severityLevelFromString } from '@sentry/utils';\nimport { AppState } from 'react-native';\n\nimport { breadcrumbFromObject } from '../breadcrumb';\nimport type { NativeDeviceContextsResponse } from '../NativeRNSentry';\nimport { NATIVE } from '../wrapper';\n\n/** Load device context from native. */\nexport class DeviceContext implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'DeviceContext';\n\n /**\n * @inheritDoc\n */\n public name: string = DeviceContext.id;\n\n /**\n * @inheritDoc\n */\n public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {\n addGlobalEventProcessor(async (event: Event) => {\n const self = getCurrentHub().getIntegration(DeviceContext);\n if (!self) {\n return event;\n }\n\n let native: NativeDeviceContextsResponse | null = null;\n try {\n native = await NATIVE.fetchNativeDeviceContexts();\n } catch (e) {\n logger.log(`Failed to get device context from native: ${e}`);\n }\n\n if (!native) {\n return event;\n }\n\n const nativeUser = native.user;\n if (!event.user && nativeUser) {\n event.user = nativeUser;\n }\n\n let nativeContexts = native.contexts;\n if (AppState.currentState !== 'unknown') {\n nativeContexts = nativeContexts || {};\n nativeContexts.app = {\n ...nativeContexts.app,\n in_foreground: AppState.currentState === 'active',\n };\n }\n if (nativeContexts) {\n event.contexts = { ...nativeContexts, ...event.contexts };\n }\n\n const nativeTags = native.tags;\n if (nativeTags) {\n event.tags = { ...nativeTags, ...event.tags };\n }\n\n const nativeExtra = native.extra;\n if (nativeExtra) {\n event.extra = { ...nativeExtra, ...event.extra };\n }\n\n const nativeFingerprint = native.fingerprint;\n if (nativeFingerprint) {\n event.fingerprint = (event.fingerprint ?? []).concat(\n nativeFingerprint.filter(item => (event.fingerprint ?? []).indexOf(item) < 0),\n );\n }\n\n const nativeLevel = typeof native['level'] === 'string' ? severityLevelFromString(native['level']) : undefined;\n if (!event.level && nativeLevel) {\n event.level = nativeLevel;\n }\n\n const nativeEnvironment = native['environment'];\n if (!event.environment && nativeEnvironment) {\n event.environment = nativeEnvironment;\n }\n\n const nativeBreadcrumbs = Array.isArray(native['breadcrumbs'])\n ? native['breadcrumbs'].map(breadcrumbFromObject)\n : undefined;\n if (nativeBreadcrumbs) {\n event.breadcrumbs = nativeBreadcrumbs;\n }\n\n return event;\n });\n }\n}\n"]}
|
|
@@ -6,4 +6,5 @@ export { EventOrigin } from './eventorigin';
|
|
|
6
6
|
export { SdkInfo } from './sdkinfo';
|
|
7
7
|
export { ReactNativeInfo } from './reactnativeinfo';
|
|
8
8
|
export { ModulesLoader } from './modulesloader';
|
|
9
|
+
export { HermesProfiling } from '../profiling/integration';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -6,4 +6,5 @@ export { EventOrigin } from './eventorigin';
|
|
|
6
6
|
export { SdkInfo } from './sdkinfo';
|
|
7
7
|
export { ReactNativeInfo } from './reactnativeinfo';
|
|
8
8
|
export { ModulesLoader } from './modulesloader';
|
|
9
|
+
export { HermesProfiling } from '../profiling/integration';
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/integrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { DebugSymbolicator } from './debugsymbolicator';\nexport { DeviceContext } from './devicecontext';\nexport { ReactNativeErrorHandlers } from './reactnativeerrorhandlers';\nexport { Release } from './release';\nexport { EventOrigin } from './eventorigin';\nexport { SdkInfo } from './sdkinfo';\nexport { ReactNativeInfo } from './reactnativeinfo';\nexport { ModulesLoader } from './modulesloader';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/integrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export { DebugSymbolicator } from './debugsymbolicator';\nexport { DeviceContext } from './devicecontext';\nexport { ReactNativeErrorHandlers } from './reactnativeerrorhandlers';\nexport { Release } from './release';\nexport { EventOrigin } from './eventorigin';\nexport { SdkInfo } from './sdkinfo';\nexport { ReactNativeInfo } from './reactnativeinfo';\nexport { ModulesLoader } from './modulesloader';\nexport { HermesProfiling } from '../profiling/integration';\n"]}
|
|
@@ -37,6 +37,11 @@ export declare class ReactNativeErrorHandlers implements Integration {
|
|
|
37
37
|
* - The package resolution fix no longer works with 0.67 on iOS Hermes.
|
|
38
38
|
*/
|
|
39
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;
|
|
40
45
|
/**
|
|
41
46
|
* Attach the unhandled rejection handler
|
|
42
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativeerrorhandlers.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAiB,MAAM,eAAe,CAAC;AAM3E,uCAAuC;AACvC,UAAU,+BAA+B;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAOD,2CAA2C;AAC3C,qBAAa,wBAAyB,YAAW,WAAW;IAC1D;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAA8B;IAEtD;;OAEG;IACI,IAAI,EAAE,MAAM,CAA+B;IAElD,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,kBAAkB;gBACC,OAAO,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC;IASrE;;OAEG;IACI,SAAS,IAAI,IAAI;IAKxB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAuCxC;;OAEG;IACH,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"reactnativeerrorhandlers.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/reactnativeerrorhandlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAiB,MAAM,eAAe,CAAC;AAM3E,uCAAuC;AACvC,UAAU,+BAA+B;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAOD,2CAA2C;AAC3C,qBAAa,wBAAyB,YAAW,WAAW;IAC1D;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAA8B;IAEtD;;OAEG;IACI,IAAI,EAAE,MAAM,CAA+B;IAElD,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,kBAAkB;gBACC,OAAO,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC;IASrE;;OAEG;IACI,SAAS,IAAI,IAAI;IAKxB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAuCxC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAuC5B;;OAEG;IACH,OAAO,CAAC,cAAc;CAoEvB"}
|
|
@@ -43,14 +43,22 @@ export class ReactNativeErrorHandlers {
|
|
|
43
43
|
_polyfillPromise() {
|
|
44
44
|
/* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */
|
|
45
45
|
const { polyfillGlobal } = require('react-native/Libraries/Utilities/PolyfillFunctions');
|
|
46
|
-
|
|
47
|
-
const Promise = require('promise/setimmediate/es6-extensions');
|
|
46
|
+
const Promise = this._getPromisePolyfill();
|
|
48
47
|
// As of RN 0.67 only done and finally are used
|
|
49
48
|
require('promise/setimmediate/done');
|
|
50
49
|
require('promise/setimmediate/finally');
|
|
51
50
|
polyfillGlobal('Promise', () => Promise);
|
|
52
51
|
/* eslint-enable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */
|
|
53
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Single source of truth for the Promise implementation we want to use.
|
|
55
|
+
* This is important for verifying that the rejected promise tracing will work as expected.
|
|
56
|
+
*/
|
|
57
|
+
_getPromisePolyfill() {
|
|
58
|
+
/* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */
|
|
59
|
+
// Below, we follow the exact way React Native initializes its promise library, and we globally replace it.
|
|
60
|
+
return require('promise/setimmediate/es6-extensions');
|
|
61
|
+
}
|
|
54
62
|
/**
|
|
55
63
|
* Attach the unhandled rejection handler
|
|
56
64
|
*/
|
|
@@ -89,10 +97,26 @@ export class ReactNativeErrorHandlers {
|
|
|
89
97
|
*/
|
|
90
98
|
_checkPromiseAndWarn() {
|
|
91
99
|
try {
|
|
100
|
+
// `promise` package is a dependency of react-native, therefore it is always available.
|
|
101
|
+
// but it is possible that the user has installed a different version of promise
|
|
102
|
+
// or dependency that uses a different version.
|
|
103
|
+
// We have to check if the React Native Promise and the `promise` package Promise are using the same reference.
|
|
104
|
+
// If they are not, likely there are multiple versions of the `promise` package installed.
|
|
92
105
|
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
const ReactNativePromise = require('react-native/Libraries/Promise');
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
|
|
108
|
+
const PromisePackagePromise = require('promise/setimmediate/es6-extensions');
|
|
109
|
+
const UsedPromisePolyfill = this._getPromisePolyfill();
|
|
110
|
+
if (ReactNativePromise !== PromisePackagePromise) {
|
|
111
|
+
logger.warn('You appear to have multiple versions of the "promise" package installed. ' +
|
|
112
|
+
'This may cause unexpected behavior like undefined `Promise.allSettled`. ' +
|
|
113
|
+
'Please install the `promise` package manually using the exact version as the React Native package. ' +
|
|
114
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
115
|
+
}
|
|
116
|
+
// This only make sense if the user disabled the integration Polyfill
|
|
117
|
+
if (UsedPromisePolyfill !== RN_GLOBAL_OBJ.Promise) {
|
|
118
|
+
logger.warn('Unhandled promise rejections will not be caught by Sentry. ' +
|
|
119
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
96
120
|
}
|
|
97
121
|
else {
|
|
98
122
|
logger.log('Unhandled promise rejections will be caught by Sentry.');
|
|
@@ -100,7 +124,8 @@ export class ReactNativeErrorHandlers {
|
|
|
100
124
|
}
|
|
101
125
|
catch (e) {
|
|
102
126
|
// Do Nothing
|
|
103
|
-
logger.warn('Unhandled promise rejections will not be caught by Sentry.
|
|
127
|
+
logger.warn('Unhandled promise rejections will not be caught by Sentry. ' +
|
|
128
|
+
'See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.');
|
|
104
129
|
}
|
|
105
130
|
}
|
|
106
131
|
/**
|
|
@@ -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, SeverityLevel } from '@sentry/types';\nimport { addExceptionMechanism, logger } from '@sentry/utils';\n\nimport type { ReactNativeClient } from '../client';\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 /* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\n const { polyfillGlobal } = require('react-native/Libraries/Utilities/PolyfillFunctions');\n\n // Below, we follow the exact way React Native initializes its promise library, and we globally replace it.\n const Promise = require('promise/setimmediate/es6-extensions');\n\n // As of RN 0.67 only done and finally are used\n require('promise/setimmediate/done');\n require('promise/setimmediate/finally');\n\n polyfillGlobal('Promise', () => Promise);\n /* eslint-enable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\n }\n /**\n * Attach the unhandled rejection handler\n */\n private _attachUnhandledRejectionHandler(): void {\n const tracking: {\n disable: () => void;\n enable: (arg: unknown) => void;\n // eslint-disable-next-line import/no-extraneous-dependencies,@typescript-eslint/no-var-requires\n } = require('promise/setimmediate/rejection-tracking');\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: Error) => {\n if (__DEV__) {\n promiseRejectionTrackingOptions.onUnhandled(id, error);\n }\n\n getCurrentHub().captureException(error, {\n data: { id },\n originalException: error,\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 // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n const Promise = require('promise/setimmediate/es6-extensions');\n\n if (Promise !== RN_GLOBAL_OBJ.Promise) {\n logger.warn(\n 'Unhandled promise rejections will not be caught by Sentry. Read about how to fix this on our troubleshooting page.',\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. Read about how to fix this on our troubleshooting page.',\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' as SeverityLevel;\n\n addExceptionMechanism(event, {\n handled: false,\n type: 'onerror',\n });\n }\n\n currentHub.captureEvent(event, hint);\n\n if (!__DEV__) {\n void client.flush(options.shutdownTimeout || 2000).then(() => {\n defaultHandler(error, isFatal);\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"]}
|
|
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, SeverityLevel } from '@sentry/types';\nimport { addExceptionMechanism, logger } from '@sentry/utils';\n\nimport type { ReactNativeClient } from '../client';\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 /* eslint-disable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\n const { polyfillGlobal } = require('react-native/Libraries/Utilities/PolyfillFunctions');\n\n const Promise = this._getPromisePolyfill();\n\n // As of RN 0.67 only done and finally are used\n require('promise/setimmediate/done');\n require('promise/setimmediate/finally');\n\n polyfillGlobal('Promise', () => Promise);\n /* eslint-enable import/no-extraneous-dependencies,@typescript-eslint/no-var-requires */\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: {\n disable: () => void;\n enable: (arg: unknown) => void;\n // eslint-disable-next-line import/no-extraneous-dependencies,@typescript-eslint/no-var-requires\n } = require('promise/setimmediate/rejection-tracking');\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: Error) => {\n if (__DEV__) {\n promiseRejectionTrackingOptions.onUnhandled(id, error);\n }\n\n getCurrentHub().captureException(error, {\n data: { id },\n originalException: error,\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 // eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies\n const ReactNativePromise = require('react-native/Libraries/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' as SeverityLevel;\n\n addExceptionMechanism(event, {\n handled: false,\n type: 'onerror',\n });\n }\n\n currentHub.captureEvent(event, hint);\n\n if (!__DEV__) {\n void client.flush(options.shutdownTimeout || 2000).then(() => {\n defaultHandler(error, isFatal);\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"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { RewriteFrames } from '@sentry/integrations';
|
|
2
|
+
export declare const ANDROID_DEFAULT_BUNDLE_NAME = "app:///index.android.bundle";
|
|
3
|
+
export declare const IOS_DEFAULT_BUNDLE_NAME = "app:///main.jsbundle";
|
|
2
4
|
/**
|
|
3
5
|
* Creates React Native default rewrite frames integration
|
|
4
6
|
* which appends app:// to the beginning of the filename
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriteframes.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/rewriteframes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"rewriteframes.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/rewriteframes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAMrD,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,uBAAuB,yBAAyB,CAAC;AAE9D;;;;;GAKG;AACH,wBAAgB,8BAA8B,IAAI,aAAa,CAmC9D"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RewriteFrames } from '@sentry/integrations';
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
3
|
import { isExpo } from '../utils/environment';
|
|
4
|
-
const ANDROID_DEFAULT_BUNDLE_NAME = 'app:///index.android.bundle';
|
|
5
|
-
const IOS_DEFAULT_BUNDLE_NAME = 'app:///main.jsbundle';
|
|
4
|
+
export const ANDROID_DEFAULT_BUNDLE_NAME = 'app:///index.android.bundle';
|
|
5
|
+
export const IOS_DEFAULT_BUNDLE_NAME = 'app:///main.jsbundle';
|
|
6
6
|
/**
|
|
7
7
|
* Creates React Native default rewrite frames integration
|
|
8
8
|
* which appends app:// to the beginning of the filename
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriteframes.js","sourceRoot":"","sources":["../../../src/js/integrations/rewriteframes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"rewriteframes.js","sourceRoot":"","sources":["../../../src/js/integrations/rewriteframes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B;IAC5C,OAAO,IAAI,aAAa,CAAC;QACvB,QAAQ,EAAE,CAAC,KAAiB,EAAE,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;gBACnB,OAAO,KAAK,CAAC;aACd;YACD,OAAO,KAAK,CAAC,QAAQ,CAAC;YAEtB,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ;iBAC5B,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;iBACzB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;iBAC3B,OAAO,CAAC,qCAAqC,EAAE,EAAE,CAAC,CAAC;YAEtD,IAAI,KAAK,CAAC,QAAQ,KAAK,eAAe,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE;gBACrE,OAAO,KAAK,CAAC;aACd;YAED,4CAA4C;YAC5C,IAAI,MAAM,EAAE,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE;gBACzC,KAAK,CAAC,QAAQ,GAAG,2BAA2B,CAAC;gBAC7C,OAAO,KAAK,CAAC;aACd;YAED,IAAI,MAAM,EAAE,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;gBACrC,KAAK,CAAC,QAAQ,GAAG,uBAAuB,CAAC;gBACzC,OAAO,KAAK,CAAC;aACd;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC;YAC3B,wCAAwC;YACxC,KAAK,CAAC,QAAQ;gBACZ,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACzG,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { RewriteFrames } from '@sentry/integrations';\nimport type { StackFrame } from '@sentry/types';\nimport { Platform } from 'react-native';\n\nimport { isExpo } from '../utils/environment';\n\nexport const ANDROID_DEFAULT_BUNDLE_NAME = 'app:///index.android.bundle';\nexport const IOS_DEFAULT_BUNDLE_NAME = 'app:///main.jsbundle';\n\n/**\n * Creates React Native default rewrite frames integration\n * which appends app:// to the beginning of the filename\n * and removes file://, 'address at' prefixes, CodePush postfix,\n * and Expo bundle postfix.\n */\nexport function createReactNativeRewriteFrames(): RewriteFrames {\n return new RewriteFrames({\n iteratee: (frame: StackFrame) => {\n if (!frame.filename) {\n return frame;\n }\n delete frame.abs_path;\n\n frame.filename = frame.filename\n .replace(/^file:\\/\\//, '')\n .replace(/^address at /, '')\n .replace(/^.*\\/[^.]+(\\.app|CodePush|.*(?=\\/))/, '');\n\n if (frame.filename === '[native code]' || frame.filename === 'native') {\n return frame;\n }\n\n // Expo adds hash to the end of bundle names\n if (isExpo() && Platform.OS === 'android') {\n frame.filename = ANDROID_DEFAULT_BUNDLE_NAME;\n return frame;\n }\n\n if (isExpo() && Platform.OS === 'ios') {\n frame.filename = IOS_DEFAULT_BUNDLE_NAME;\n return frame;\n }\n\n const appPrefix = 'app://';\n // We always want to have a triple slash\n frame.filename =\n frame.filename.indexOf('/') === 0 ? `${appPrefix}${frame.filename}` : `${appPrefix}/${frame.filename}`;\n return frame;\n },\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkinfo.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/sdkinfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAW,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AAMlG,aAAK,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC;AAEnF,eAAO,MAAM,cAAc,EAAE,cAS5B,CAAC;AAEF,sCAAsC;AACtC,qBAAa,OAAQ,YAAW,WAAW;IACzC;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAAa;IAErC;;OAEG;IACI,IAAI,EAAE,MAAM,CAAc;IAEjC,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;OAEG;IACI,SAAS,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"sdkinfo.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/sdkinfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAW,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AAMlG,aAAK,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC;AAEnF,eAAO,MAAM,cAAc,EAAE,cAS5B,CAAC;AAEF,sCAAsC;AACtC,qBAAa,OAAQ,YAAW,WAAW;IACzC;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAAa;IAErC;;OAEG;IACI,IAAI,EAAE,MAAM,CAAc;IAEjC,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;OAEG;IACI,SAAS,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;CA4B7E"}
|
|
@@ -26,9 +26,8 @@ export class SdkInfo {
|
|
|
26
26
|
*/
|
|
27
27
|
setupOnce(addGlobalEventProcessor) {
|
|
28
28
|
addGlobalEventProcessor((event) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
-
// The native SDK info package here is only used on iOS as `beforeSend` is not called on `captureEnvelope`.
|
|
30
29
|
// this._nativeSdkInfo should be defined a following time so this call won't always be awaited.
|
|
31
|
-
if (
|
|
30
|
+
if (this._nativeSdkPackage === null) {
|
|
32
31
|
try {
|
|
33
32
|
this._nativeSdkPackage = yield NATIVE.fetchNativeSdkInfo();
|
|
34
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkinfo.js","sourceRoot":"","sources":["../../../src/js/integrations/sdkinfo.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIpC,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,WAAW;SACrB;KACF;IACD,OAAO,EAAE,WAAW;CACrB,CAAC;AAEF,sCAAsC;AACtC,MAAM,OAAO,OAAO;IAApB;QAME;;WAEG;QACI,SAAI,GAAW,OAAO,CAAC,EAAE,CAAC;QAEzB,sBAAiB,GAAmB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"sdkinfo.js","sourceRoot":"","sources":["../../../src/js/integrations/sdkinfo.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIpC,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,WAAW;SACrB;KACF;IACD,OAAO,EAAE,WAAW;CACrB,CAAC;AAEF,sCAAsC;AACtC,MAAM,OAAO,OAAO;IAApB;QAME;;WAEG;QACI,SAAI,GAAW,OAAO,CAAC,EAAE,CAAC;QAEzB,sBAAiB,GAAmB,IAAI,CAAC;IAiCnD,CAAC;IA/BC;;OAEG;IACI,SAAS,CAAC,uBAAoD;QACnE,uBAAuB,CAAC,CAAM,KAAK,EAAC,EAAE;YACpC,+FAA+F;YAC/F,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,EAAE;gBACnC,IAAI;oBACF,IAAI,CAAC,iBAAiB,GAAG,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;iBAC5D;gBAAC,OAAO,CAAC,EAAE;oBACV,qGAAqG;oBACrG,MAAM,CAAC,IAAI,CACT,sGAAsG,CACvG,CAAC;oBACF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;iBAChB;aACF;YAED,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,YAAY,CAAC;YAChD,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;YAC5B,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC;YACvD,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC;YAChE,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG;gBACnB,wEAAwE;gBACxE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;gBAC7B,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC;aAChE,CAAC;YAEF,OAAO,KAAK,CAAC;QACf,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;;AA1CD;;GAEG;AACW,UAAE,GAAW,SAAS,CAAC","sourcesContent":["import type { EventProcessor, Integration, Package, SdkInfo as SdkInfoType } from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport { SDK_NAME, SDK_PACKAGE_NAME, SDK_VERSION } from '../version';\nimport { NATIVE } from '../wrapper';\n\ntype DefaultSdkInfo = Pick<Required<SdkInfoType>, 'name' | 'packages' | 'version'>;\n\nexport const defaultSdkInfo: DefaultSdkInfo = {\n name: SDK_NAME,\n packages: [\n {\n name: SDK_PACKAGE_NAME,\n version: SDK_VERSION,\n },\n ],\n version: SDK_VERSION,\n};\n\n/** Default SdkInfo instrumentation */\nexport class SdkInfo implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'SdkInfo';\n\n /**\n * @inheritDoc\n */\n public name: string = SdkInfo.id;\n\n private _nativeSdkPackage: Package | null = null;\n\n /**\n * @inheritDoc\n */\n public setupOnce(addGlobalEventProcessor: (e: EventProcessor) => void): void {\n addGlobalEventProcessor(async event => {\n // this._nativeSdkInfo should be defined a following time so this call won't always be awaited.\n if (this._nativeSdkPackage === null) {\n try {\n this._nativeSdkPackage = await NATIVE.fetchNativeSdkInfo();\n } catch (e) {\n // If this fails, go ahead as usual as we would rather have the event be sent with a package missing.\n logger.warn(\n '[SdkInfo] Native SDK Info retrieval failed...something could be wrong with your Sentry installation:',\n );\n logger.warn(e);\n }\n }\n\n event.platform = event.platform || 'javascript';\n event.sdk = event.sdk || {};\n event.sdk.name = event.sdk.name || defaultSdkInfo.name;\n event.sdk.version = event.sdk.version || defaultSdkInfo.version;\n event.sdk.packages = [\n // default packages are added by baseclient and should not be added here\n ...(event.sdk.packages || []),\n ...((this._nativeSdkPackage && [this._nativeSdkPackage]) || []),\n ];\n\n return event;\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RawThreadCpuProfile } from './types';
|
|
2
|
+
export declare const PROFILE_QUEUE: {
|
|
3
|
+
get: (key: string) => RawThreadCpuProfile | undefined;
|
|
4
|
+
add: (key: string, value: RawThreadCpuProfile) => void;
|
|
5
|
+
delete: (key: string) => boolean;
|
|
6
|
+
clear: () => void;
|
|
7
|
+
size: () => number;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,eAAO,MAAM,aAAa;;;;;;CAAiD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/js/profiling/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAA8B,EAAE,CAAC,CAAC","sourcesContent":["import { makeFifoCache } from '@sentry/utils';\n\nimport type { RawThreadCpuProfile } from './types';\n\nexport const PROFILE_QUEUE = makeFifoCache<string, RawThreadCpuProfile>(20);\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ThreadCpuSample, ThreadId } from '@sentry/types';
|
|
2
|
+
import type * as Hermes from './hermes';
|
|
3
|
+
import type { RawThreadCpuProfile } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Converts a Hermes profile to a Sentry profile.
|
|
6
|
+
*
|
|
7
|
+
* Maps Hermes samples to Sentry samples.
|
|
8
|
+
* Maps Hermes stack frames to Sentry frames.
|
|
9
|
+
* Hermes stack frame is an object representing a function call in the stack
|
|
10
|
+
* with a link to its parent stack frame. Root of the represented stack tree
|
|
11
|
+
* is main function call in Hermes that is [root] stack frame.
|
|
12
|
+
*
|
|
13
|
+
* @returns Sentry profile or null if no samples are found.
|
|
14
|
+
*/
|
|
15
|
+
export declare function convertToSentryProfile(hermesProfile: Hermes.Profile): RawThreadCpuProfile | null;
|
|
16
|
+
/**
|
|
17
|
+
* Maps Hermes samples to Sentry samples.
|
|
18
|
+
* Calculates the elapsed time since the first sample based on the absolute timestamps of the Hermes samples.
|
|
19
|
+
* Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.
|
|
20
|
+
* @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs
|
|
21
|
+
*/
|
|
22
|
+
export declare function mapSamples(hermesSamples: Hermes.Sample[], maxElapsedSinceStartNs?: number): {
|
|
23
|
+
samples: ThreadCpuSample[];
|
|
24
|
+
hermesStacks: Set<Hermes.StackFrameId>;
|
|
25
|
+
jsThreads: Set<ThreadId>;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=convertHermesProfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convertHermesProfile.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/convertHermesProfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoC,eAAe,EAAkB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKjH,OAAO,KAAK,KAAK,MAAM,MAAM,UAAU,CAAC;AAGxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAWnD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,CAAC,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAwChG;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,EAC9B,sBAAsB,GAAE,MAAgC,GACvD;IACD,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACvC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;CAC1B,CA+BA"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { logger } from '@sentry/utils';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
|
+
import { ANDROID_DEFAULT_BUNDLE_NAME, IOS_DEFAULT_BUNDLE_NAME } from '../integrations/rewriteframes';
|
|
4
|
+
import { parseHermesStackFrameFunctionName } from './hermes';
|
|
5
|
+
import { MAX_PROFILE_DURATION_MS } from './integration';
|
|
6
|
+
const MS_TO_NS = 1e6;
|
|
7
|
+
const MAX_PROFILE_DURATION_NS = MAX_PROFILE_DURATION_MS * MS_TO_NS;
|
|
8
|
+
const ANONYMOUS_FUNCTION_NAME = 'anonymous';
|
|
9
|
+
const UNKNOWN_STACK_ID = -1;
|
|
10
|
+
const JS_THREAD_NAME = 'JavaScriptThread';
|
|
11
|
+
const JS_THREAD_PRIORITY = 1;
|
|
12
|
+
const DEFAULT_BUNDLE_NAME = Platform.OS === 'android' ? ANDROID_DEFAULT_BUNDLE_NAME : Platform.OS === 'ios' ? IOS_DEFAULT_BUNDLE_NAME : undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a Hermes profile to a Sentry profile.
|
|
15
|
+
*
|
|
16
|
+
* Maps Hermes samples to Sentry samples.
|
|
17
|
+
* Maps Hermes stack frames to Sentry frames.
|
|
18
|
+
* Hermes stack frame is an object representing a function call in the stack
|
|
19
|
+
* with a link to its parent stack frame. Root of the represented stack tree
|
|
20
|
+
* is main function call in Hermes that is [root] stack frame.
|
|
21
|
+
*
|
|
22
|
+
* @returns Sentry profile or null if no samples are found.
|
|
23
|
+
*/
|
|
24
|
+
export function convertToSentryProfile(hermesProfile) {
|
|
25
|
+
if (hermesProfile.samples.length === 0) {
|
|
26
|
+
logger.warn('[Profiling] No samples found in profile.');
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const { samples, hermesStacks, jsThreads } = mapSamples(hermesProfile.samples);
|
|
30
|
+
const { frames, hermesStackFrameIdToSentryFrameIdMap } = mapFrames(hermesProfile.stackFrames);
|
|
31
|
+
const { stacks, hermesStackToSentryStackMap } = mapStacks(hermesStacks, hermesProfile.stackFrames, hermesStackFrameIdToSentryFrameIdMap);
|
|
32
|
+
for (const sample of samples) {
|
|
33
|
+
const sentryStackId = hermesStackToSentryStackMap.get(sample.stack_id);
|
|
34
|
+
if (sentryStackId === undefined) {
|
|
35
|
+
logger.error(`[Profiling] Hermes Stack ID ${sample.stack_id} not found when mapping to Sentry Stack ID.`);
|
|
36
|
+
sample.stack_id = UNKNOWN_STACK_ID;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
sample.stack_id = sentryStackId;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const thread_metadata = {};
|
|
43
|
+
for (const jsThreadId of jsThreads) {
|
|
44
|
+
thread_metadata[jsThreadId] = {
|
|
45
|
+
name: JS_THREAD_NAME,
|
|
46
|
+
priority: JS_THREAD_PRIORITY,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
samples,
|
|
51
|
+
frames,
|
|
52
|
+
stacks,
|
|
53
|
+
thread_metadata,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Maps Hermes samples to Sentry samples.
|
|
58
|
+
* Calculates the elapsed time since the first sample based on the absolute timestamps of the Hermes samples.
|
|
59
|
+
* Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.
|
|
60
|
+
* @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs
|
|
61
|
+
*/
|
|
62
|
+
export function mapSamples(hermesSamples, maxElapsedSinceStartNs = MAX_PROFILE_DURATION_NS) {
|
|
63
|
+
const jsThreads = new Set();
|
|
64
|
+
const hermesStacks = new Set();
|
|
65
|
+
const start = Number(hermesSamples[0].ts);
|
|
66
|
+
const samples = [];
|
|
67
|
+
for (const hermesSample of hermesSamples) {
|
|
68
|
+
jsThreads.add(hermesSample.tid);
|
|
69
|
+
hermesStacks.add(hermesSample.sf);
|
|
70
|
+
const elapsed_since_start_ns = (Number(hermesSample.ts) - start) * 1e3;
|
|
71
|
+
if (elapsed_since_start_ns >= maxElapsedSinceStartNs) {
|
|
72
|
+
logger.warn(`[Profiling] Sample has elapsed time since start ${elapsed_since_start_ns}ns ` +
|
|
73
|
+
`greater than the max elapsed time ${maxElapsedSinceStartNs}ns.`);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
samples.push({
|
|
77
|
+
stack_id: hermesSample.sf,
|
|
78
|
+
thread_id: hermesSample.tid,
|
|
79
|
+
elapsed_since_start_ns: elapsed_since_start_ns.toFixed(0),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
samples,
|
|
84
|
+
hermesStacks,
|
|
85
|
+
jsThreads,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Maps Hermes StackFrames tree represented as an JS object to a Sentry frames array.
|
|
90
|
+
* Converts line and columns strings to numbers.
|
|
91
|
+
* @returns the mapped Sentry frames
|
|
92
|
+
*/
|
|
93
|
+
function mapFrames(hermesStackFrames) {
|
|
94
|
+
const frames = [];
|
|
95
|
+
const hermesStackFrameIdToSentryFrameIdMap = new Map();
|
|
96
|
+
for (const key in hermesStackFrames) {
|
|
97
|
+
// asc order based on the key is not guaranteed
|
|
98
|
+
if (!Object.prototype.hasOwnProperty.call(hermesStackFrames, key)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
hermesStackFrameIdToSentryFrameIdMap.set(Number(key), frames.length);
|
|
102
|
+
const hermesFrame = hermesStackFrames[key];
|
|
103
|
+
const functionName = parseHermesStackFrameFunctionName(hermesFrame.name);
|
|
104
|
+
frames.push({
|
|
105
|
+
function: functionName || ANONYMOUS_FUNCTION_NAME,
|
|
106
|
+
file: hermesFrame.category == 'JavaScript' ? DEFAULT_BUNDLE_NAME : undefined,
|
|
107
|
+
lineno: hermesFrame.line !== undefined ? Number(hermesFrame.line) : undefined,
|
|
108
|
+
colno: hermesFrame.column !== undefined ? Number(hermesFrame.column) : undefined,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
frames,
|
|
113
|
+
hermesStackFrameIdToSentryFrameIdMap,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Maps Hermes stack frame IDs to Sentry stack arrays.
|
|
118
|
+
* Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.
|
|
119
|
+
* @returns the mapped Sentry stacks and a map from Hermes stack IDs to Sentry stack IDs (indices in the stacks array)
|
|
120
|
+
*/
|
|
121
|
+
function mapStacks(hermesStacks, hermesStackFrames, hermesStackFrameIdToSentryFrameIdMap) {
|
|
122
|
+
const hermesStackToSentryStackMap = new Map();
|
|
123
|
+
const stacks = [];
|
|
124
|
+
for (const hermesStackFunctionFrameId of hermesStacks) {
|
|
125
|
+
const stackId = stacks.length;
|
|
126
|
+
hermesStackToSentryStackMap.set(hermesStackFunctionFrameId, stackId);
|
|
127
|
+
const stack = [];
|
|
128
|
+
let currentHermesFrameId = hermesStackFunctionFrameId;
|
|
129
|
+
while (currentHermesFrameId !== undefined) {
|
|
130
|
+
const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);
|
|
131
|
+
sentryFrameId !== undefined && stack.push(sentryFrameId);
|
|
132
|
+
currentHermesFrameId = hermesStackFrames[currentHermesFrameId] && hermesStackFrames[currentHermesFrameId].parent;
|
|
133
|
+
}
|
|
134
|
+
stacks.push(stack);
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
stacks,
|
|
138
|
+
hermesStackToSentryStackMap,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=convertHermesProfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convertHermesProfile.js","sourceRoot":"","sources":["../../../src/js/profiling/convertHermesProfile.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameId, StackId, ThreadCpuFrame, ThreadCpuSample, ThreadCpuStack, ThreadId } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport { Platform } from 'react-native';\n\nimport { ANDROID_DEFAULT_BUNDLE_NAME, IOS_DEFAULT_BUNDLE_NAME } from '../integrations/rewriteframes';\nimport type * as Hermes from './hermes';\nimport { parseHermesStackFrameFunctionName } from './hermes';\nimport { MAX_PROFILE_DURATION_MS } from './integration';\nimport type { RawThreadCpuProfile } from './types';\n\nconst MS_TO_NS = 1e6;\nconst MAX_PROFILE_DURATION_NS = MAX_PROFILE_DURATION_MS * MS_TO_NS;\nconst ANONYMOUS_FUNCTION_NAME = 'anonymous';\nconst UNKNOWN_STACK_ID = -1;\nconst JS_THREAD_NAME = 'JavaScriptThread';\nconst JS_THREAD_PRIORITY = 1;\nconst DEFAULT_BUNDLE_NAME =\n Platform.OS === 'android' ? ANDROID_DEFAULT_BUNDLE_NAME : Platform.OS === 'ios' ? IOS_DEFAULT_BUNDLE_NAME : undefined;\n\n/**\n * Converts a Hermes profile to a Sentry profile.\n *\n * Maps Hermes samples to Sentry samples.\n * Maps Hermes stack frames to Sentry frames.\n * Hermes stack frame is an object representing a function call in the stack\n * with a link to its parent stack frame. Root of the represented stack tree\n * is main function call in Hermes that is [root] stack frame.\n *\n * @returns Sentry profile or null if no samples are found.\n */\nexport function convertToSentryProfile(hermesProfile: Hermes.Profile): RawThreadCpuProfile | null {\n if (hermesProfile.samples.length === 0) {\n logger.warn('[Profiling] No samples found in profile.');\n return null;\n }\n\n const { samples, hermesStacks, jsThreads } = mapSamples(hermesProfile.samples);\n\n const { frames, hermesStackFrameIdToSentryFrameIdMap } = mapFrames(hermesProfile.stackFrames);\n\n const { stacks, hermesStackToSentryStackMap } = mapStacks(\n hermesStacks,\n hermesProfile.stackFrames,\n hermesStackFrameIdToSentryFrameIdMap,\n );\n\n for (const sample of samples) {\n const sentryStackId = hermesStackToSentryStackMap.get(sample.stack_id);\n if (sentryStackId === undefined) {\n logger.error(`[Profiling] Hermes Stack ID ${sample.stack_id} not found when mapping to Sentry Stack ID.`);\n sample.stack_id = UNKNOWN_STACK_ID;\n } else {\n sample.stack_id = sentryStackId;\n }\n }\n\n const thread_metadata: Record<ThreadId, { name?: string; priority?: number }> = {};\n for (const jsThreadId of jsThreads) {\n thread_metadata[jsThreadId] = {\n name: JS_THREAD_NAME,\n priority: JS_THREAD_PRIORITY,\n };\n }\n\n return {\n samples,\n frames,\n stacks,\n thread_metadata,\n };\n}\n\n/**\n * Maps Hermes samples to Sentry samples.\n * Calculates the elapsed time since the first sample based on the absolute timestamps of the Hermes samples.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs\n */\nexport function mapSamples(\n hermesSamples: Hermes.Sample[],\n maxElapsedSinceStartNs: number = MAX_PROFILE_DURATION_NS,\n): {\n samples: ThreadCpuSample[];\n hermesStacks: Set<Hermes.StackFrameId>;\n jsThreads: Set<ThreadId>;\n} {\n const jsThreads = new Set<ThreadId>();\n const hermesStacks = new Set<Hermes.StackFrameId>();\n\n const start = Number(hermesSamples[0].ts);\n const samples: ThreadCpuSample[] = [];\n for (const hermesSample of hermesSamples) {\n jsThreads.add(hermesSample.tid);\n hermesStacks.add(hermesSample.sf);\n\n const elapsed_since_start_ns = (Number(hermesSample.ts) - start) * 1e3;\n if (elapsed_since_start_ns >= maxElapsedSinceStartNs) {\n logger.warn(\n `[Profiling] Sample has elapsed time since start ${elapsed_since_start_ns}ns ` +\n `greater than the max elapsed time ${maxElapsedSinceStartNs}ns.`,\n );\n break;\n }\n\n samples.push({\n stack_id: hermesSample.sf,\n thread_id: hermesSample.tid,\n elapsed_since_start_ns: elapsed_since_start_ns.toFixed(0),\n });\n }\n\n return {\n samples,\n hermesStacks,\n jsThreads,\n };\n}\n\n/**\n * Maps Hermes StackFrames tree represented as an JS object to a Sentry frames array.\n * Converts line and columns strings to numbers.\n * @returns the mapped Sentry frames\n */\nfunction mapFrames(hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>): {\n frames: ThreadCpuFrame[];\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>;\n} {\n const frames: ThreadCpuFrame[] = [];\n const hermesStackFrameIdToSentryFrameIdMap = new Map<Hermes.StackFrameId, FrameId>();\n for (const key in hermesStackFrames) {\n // asc order based on the key is not guaranteed\n if (!Object.prototype.hasOwnProperty.call(hermesStackFrames, key)) {\n continue;\n }\n hermesStackFrameIdToSentryFrameIdMap.set(Number(key), frames.length);\n const hermesFrame = hermesStackFrames[key];\n\n const functionName = parseHermesStackFrameFunctionName(hermesFrame.name);\n frames.push({\n function: functionName || ANONYMOUS_FUNCTION_NAME,\n file: hermesFrame.category == 'JavaScript' ? DEFAULT_BUNDLE_NAME : undefined,\n lineno: hermesFrame.line !== undefined ? Number(hermesFrame.line) : undefined,\n colno: hermesFrame.column !== undefined ? Number(hermesFrame.column) : undefined,\n });\n }\n\n return {\n frames,\n hermesStackFrameIdToSentryFrameIdMap,\n };\n}\n\n/**\n * Maps Hermes stack frame IDs to Sentry stack arrays.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry stacks and a map from Hermes stack IDs to Sentry stack IDs (indices in the stacks array)\n */\nfunction mapStacks(\n hermesStacks: Set<Hermes.StackFrameId>,\n hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>,\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>,\n): {\n stacks: ThreadCpuStack[];\n hermesStackToSentryStackMap: Map<Hermes.StackFrameId, StackId>;\n} {\n const hermesStackToSentryStackMap = new Map<Hermes.StackFrameId, StackId>();\n const stacks: ThreadCpuStack[] = [];\n for (const hermesStackFunctionFrameId of hermesStacks) {\n const stackId = stacks.length;\n hermesStackToSentryStackMap.set(hermesStackFunctionFrameId, stackId);\n const stack: ThreadCpuStack = [];\n let currentHermesFrameId: Hermes.StackFrameId | undefined = hermesStackFunctionFrameId;\n while (currentHermesFrameId !== undefined) {\n const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);\n sentryFrameId !== undefined && stack.push(sentryFrameId);\n currentHermesFrameId = hermesStackFrames[currentHermesFrameId] && hermesStackFrames[currentHermesFrameId].parent;\n }\n stacks.push(stack);\n }\n\n return {\n stacks,\n hermesStackToSentryStackMap,\n };\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { RawThreadCpuProfile } from './types';
|
|
2
|
+
export declare type StackFrameId = number;
|
|
3
|
+
export declare type MicrosecondsSinceBoot = string;
|
|
4
|
+
export interface TraceEvent {
|
|
5
|
+
name: string;
|
|
6
|
+
ph: string;
|
|
7
|
+
cat: string;
|
|
8
|
+
pid: number;
|
|
9
|
+
ts: MicrosecondsSinceBoot;
|
|
10
|
+
tid: string;
|
|
11
|
+
args: {
|
|
12
|
+
name?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface Sample {
|
|
16
|
+
cpu: string;
|
|
17
|
+
name: string;
|
|
18
|
+
ts: MicrosecondsSinceBoot;
|
|
19
|
+
pid: number;
|
|
20
|
+
tid: string;
|
|
21
|
+
weight: string;
|
|
22
|
+
sf: StackFrameId;
|
|
23
|
+
}
|
|
24
|
+
export interface StackFrame {
|
|
25
|
+
line?: string;
|
|
26
|
+
column?: string;
|
|
27
|
+
funcLine?: string;
|
|
28
|
+
funcColumn?: string;
|
|
29
|
+
name: string;
|
|
30
|
+
category: string;
|
|
31
|
+
parent?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface Profile {
|
|
34
|
+
traceEvents: TraceEvent[];
|
|
35
|
+
samples: Sample[];
|
|
36
|
+
stackFrames: Record<string, StackFrame>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Hermes Profile Stack Frame Name contains function name and file path.
|
|
40
|
+
*
|
|
41
|
+
* `foo(/path/to/file.js:1:2)` -> `foo`
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseHermesStackFrameFunctionName(hermesName: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Starts Hermes Sampling Profiler and returns the timestamp when profiling started in nanoseconds.
|
|
46
|
+
*/
|
|
47
|
+
export declare function startProfiling(): number | null;
|
|
48
|
+
/**
|
|
49
|
+
* Stops Hermes Sampling Profiler and returns the profile.
|
|
50
|
+
*/
|
|
51
|
+
export declare function stopProfiling(): RawThreadCpuProfile | null;
|
|
52
|
+
//# sourceMappingURL=hermes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/hermes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,oBAAY,YAAY,GAAG,MAAM,CAAC;AAClC,oBAAY,qBAAqB,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,YAAY,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAI5E;AAID;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAQ9C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,mBAAmB,GAAG,IAAI,CAM1D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { NATIVE } from '../wrapper';
|
|
2
|
+
import { convertToSentryProfile } from './convertHermesProfile';
|
|
3
|
+
/**
|
|
4
|
+
* Hermes Profile Stack Frame Name contains function name and file path.
|
|
5
|
+
*
|
|
6
|
+
* `foo(/path/to/file.js:1:2)` -> `foo`
|
|
7
|
+
*/
|
|
8
|
+
export function parseHermesStackFrameFunctionName(hermesName) {
|
|
9
|
+
const indexOfLeftParenthesis = hermesName.indexOf('(');
|
|
10
|
+
const name = indexOfLeftParenthesis !== -1 ? hermesName.substring(0, indexOfLeftParenthesis) : hermesName;
|
|
11
|
+
return name;
|
|
12
|
+
}
|
|
13
|
+
const MS_TO_NS = 1e6;
|
|
14
|
+
/**
|
|
15
|
+
* Starts Hermes Sampling Profiler and returns the timestamp when profiling started in nanoseconds.
|
|
16
|
+
*/
|
|
17
|
+
export function startProfiling() {
|
|
18
|
+
const started = NATIVE.startProfiling();
|
|
19
|
+
if (!started) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const profileStartTimestampNs = Date.now() * MS_TO_NS;
|
|
23
|
+
return profileStartTimestampNs;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Stops Hermes Sampling Profiler and returns the profile.
|
|
27
|
+
*/
|
|
28
|
+
export function stopProfiling() {
|
|
29
|
+
const hermesProfile = NATIVE.stopProfiling();
|
|
30
|
+
if (!hermesProfile) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return convertToSentryProfile(hermesProfile);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=hermes.js.map
|