@sentry/browser 6.17.5 → 6.17.8
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/build/bundle.es6.js +206 -361
- package/build/bundle.es6.js.map +1 -1
- package/build/bundle.es6.min.js +2 -2
- package/build/bundle.es6.min.js.map +1 -1
- package/build/bundle.js +250 -375
- package/build/bundle.js.map +1 -1
- package/build/bundle.min.js +2 -2
- package/build/bundle.min.js.map +1 -1
- package/dist/eventbuilder.d.ts.map +1 -1
- package/dist/eventbuilder.js +4 -11
- package/dist/eventbuilder.js.map +1 -1
- package/dist/integrations/linkederrors.d.ts.map +1 -1
- package/dist/integrations/linkederrors.js +1 -3
- package/dist/integrations/linkederrors.js.map +1 -1
- package/dist/parsers.d.ts +7 -7
- package/dist/parsers.d.ts.map +1 -1
- package/dist/parsers.js +52 -40
- package/dist/parsers.js.map +1 -1
- package/dist/stack-parsers.d.ts +7 -0
- package/dist/stack-parsers.d.ts.map +1 -0
- package/dist/stack-parsers.js +117 -0
- package/dist/stack-parsers.js.map +1 -0
- package/esm/eventbuilder.d.ts.map +1 -1
- package/esm/eventbuilder.js +5 -12
- package/esm/eventbuilder.js.map +1 -1
- package/esm/integrations/linkederrors.d.ts.map +1 -1
- package/esm/integrations/linkederrors.js +2 -4
- package/esm/integrations/linkederrors.js.map +1 -1
- package/esm/parsers.d.ts +7 -7
- package/esm/parsers.d.ts.map +1 -1
- package/esm/parsers.js +50 -38
- package/esm/parsers.js.map +1 -1
- package/esm/stack-parsers.d.ts +7 -0
- package/esm/stack-parsers.d.ts.map +1 -0
- package/esm/stack-parsers.js +116 -0
- package/esm/stack-parsers.js.map +1 -0
- package/package.json +4 -7
- package/dist/tracekit.d.ts +0 -38
- package/dist/tracekit.d.ts.map +0 -1
- package/dist/tracekit.js +0 -259
- package/dist/tracekit.js.map +0 -1
- package/esm/tracekit.d.ts +0 -38
- package/esm/tracekit.d.ts.map +0 -1
- package/esm/tracekit.js +0 -257
- package/esm/tracekit.js.map +0 -1
package/build/bundle.es6.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @sentry/browser 6.17.
|
|
1
|
+
/*! @sentry/browser 6.17.8 (db493a0) | https://github.com/getsentry/sentry-javascript */
|
|
2
2
|
var Sentry = (function (exports) {
|
|
3
3
|
/**
|
|
4
4
|
* TODO(v7): Remove this enum and replace with SeverityLevel
|
|
@@ -49,41 +49,7 @@ var Sentry = (function (exports) {
|
|
|
49
49
|
* @returns true if this is a debug build
|
|
50
50
|
*/
|
|
51
51
|
function isDebugBuild() {
|
|
52
|
-
return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Figures out if we're building a browser bundle.
|
|
56
|
-
*
|
|
57
|
-
* @returns true if this is a browser bundle build.
|
|
58
|
-
*/
|
|
59
|
-
function isBrowserBundle() {
|
|
60
|
-
return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
|
|
65
|
-
* you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
|
|
66
|
-
*/
|
|
67
|
-
/**
|
|
68
|
-
* Checks whether we're in the Node.js or Browser environment
|
|
69
|
-
*
|
|
70
|
-
* @returns Answer to given question
|
|
71
|
-
*/
|
|
72
|
-
function isNodeEnv() {
|
|
73
|
-
// explicitly check for browser bundles as those can be optimized statically
|
|
74
|
-
// by terser/rollup.
|
|
75
|
-
return (!isBrowserBundle() &&
|
|
76
|
-
Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]');
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Requires a module which is protected against bundler minification.
|
|
80
|
-
*
|
|
81
|
-
* @param request The module path to resolve
|
|
82
|
-
*/
|
|
83
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
84
|
-
function dynamicRequire(mod, request) {
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
86
|
-
return mod.require(request);
|
|
52
|
+
return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !true;
|
|
87
53
|
}
|
|
88
54
|
|
|
89
55
|
/**
|
|
@@ -97,9 +63,7 @@ var Sentry = (function (exports) {
|
|
|
97
63
|
* @returns Global scope object
|
|
98
64
|
*/
|
|
99
65
|
function getGlobalObject() {
|
|
100
|
-
return (
|
|
101
|
-
? global
|
|
102
|
-
: typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
|
|
66
|
+
return ( typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
|
|
103
67
|
? window // eslint-disable-line no-restricted-globals
|
|
104
68
|
: typeof self !== 'undefined'
|
|
105
69
|
? self
|
|
@@ -603,6 +567,53 @@ var Sentry = (function (exports) {
|
|
|
603
567
|
return [memoize, unmemoize];
|
|
604
568
|
}
|
|
605
569
|
|
|
570
|
+
const STACKTRACE_LIMIT = 50;
|
|
571
|
+
/**
|
|
572
|
+
* Creates a stack parser with the supplied line parsers
|
|
573
|
+
*
|
|
574
|
+
* StackFrames are returned in the correct order for Sentry Exception
|
|
575
|
+
* frames and with Sentry SDK internal frames removed from the top and bottom
|
|
576
|
+
*
|
|
577
|
+
* */
|
|
578
|
+
function createStackParser(...parsers) {
|
|
579
|
+
return (stack, skipFirst = 0) => {
|
|
580
|
+
const frames = [];
|
|
581
|
+
for (const line of stack.split('\n').slice(skipFirst)) {
|
|
582
|
+
for (const parser of parsers) {
|
|
583
|
+
const frame = parser(line);
|
|
584
|
+
if (frame) {
|
|
585
|
+
frames.push(frame);
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return stripSentryFramesAndReverse(frames);
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* @hidden
|
|
595
|
+
*/
|
|
596
|
+
function stripSentryFramesAndReverse(stack) {
|
|
597
|
+
if (!stack.length) {
|
|
598
|
+
return [];
|
|
599
|
+
}
|
|
600
|
+
let localStack = stack;
|
|
601
|
+
const firstFrameFunction = localStack[0].function || '';
|
|
602
|
+
const lastFrameFunction = localStack[localStack.length - 1].function || '';
|
|
603
|
+
// If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
|
|
604
|
+
if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
|
|
605
|
+
localStack = localStack.slice(1);
|
|
606
|
+
}
|
|
607
|
+
// If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)
|
|
608
|
+
if (lastFrameFunction.indexOf('sentryWrapped') !== -1) {
|
|
609
|
+
localStack = localStack.slice(0, -1);
|
|
610
|
+
}
|
|
611
|
+
// The frame where the crash happened, should be the last entry in the array
|
|
612
|
+
return localStack
|
|
613
|
+
.slice(0, STACKTRACE_LIMIT)
|
|
614
|
+
.map(frame => (Object.assign(Object.assign({}, frame), { filename: frame.filename || localStack[0].filename, function: frame.function || '?' })))
|
|
615
|
+
.reverse();
|
|
616
|
+
}
|
|
606
617
|
const defaultFunctionName = '<anonymous>';
|
|
607
618
|
/**
|
|
608
619
|
* Safely extract function name from itself
|
|
@@ -707,16 +718,18 @@ var Sentry = (function (exports) {
|
|
|
707
718
|
source[name] = wrapped;
|
|
708
719
|
}
|
|
709
720
|
/**
|
|
710
|
-
* Defines a non
|
|
721
|
+
* Defines a non-enumerable property on the given object.
|
|
711
722
|
*
|
|
712
|
-
* @param
|
|
713
|
-
* @param name
|
|
714
|
-
* @param value
|
|
723
|
+
* @param obj The object on which to set the property
|
|
724
|
+
* @param name The name of the property to be set
|
|
725
|
+
* @param value The value to which to set the property
|
|
715
726
|
*/
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
727
|
+
function addNonEnumerableProperty(obj, name, value) {
|
|
728
|
+
Object.defineProperty(obj, name, {
|
|
729
|
+
// enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
|
|
719
730
|
value: value,
|
|
731
|
+
writable: true,
|
|
732
|
+
configurable: true,
|
|
720
733
|
});
|
|
721
734
|
}
|
|
722
735
|
/**
|
|
@@ -1212,12 +1225,12 @@ var Sentry = (function (exports) {
|
|
|
1212
1225
|
if (!(level in global$2.console)) {
|
|
1213
1226
|
return;
|
|
1214
1227
|
}
|
|
1215
|
-
fill(global$2.console, level, function (
|
|
1228
|
+
fill(global$2.console, level, function (originalConsoleMethod) {
|
|
1216
1229
|
return function (...args) {
|
|
1217
1230
|
triggerHandlers('console', { args, level });
|
|
1218
1231
|
// this fails for some browsers. :(
|
|
1219
|
-
if (
|
|
1220
|
-
|
|
1232
|
+
if (originalConsoleMethod) {
|
|
1233
|
+
originalConsoleMethod.apply(global$2.console, args);
|
|
1221
1234
|
}
|
|
1222
1235
|
};
|
|
1223
1236
|
});
|
|
@@ -2107,23 +2120,10 @@ var Sentry = (function (exports) {
|
|
|
2107
2120
|
timeOrigin,
|
|
2108
2121
|
};
|
|
2109
2122
|
}
|
|
2110
|
-
/**
|
|
2111
|
-
* Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't
|
|
2112
|
-
* implement the API.
|
|
2113
|
-
*/
|
|
2114
|
-
function getNodePerformance() {
|
|
2115
|
-
try {
|
|
2116
|
-
const perfHooks = dynamicRequire(module, 'perf_hooks');
|
|
2117
|
-
return perfHooks.performance;
|
|
2118
|
-
}
|
|
2119
|
-
catch (_) {
|
|
2120
|
-
return undefined;
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
2123
|
/**
|
|
2124
2124
|
* The Performance API implementation for the current platform, if available.
|
|
2125
2125
|
*/
|
|
2126
|
-
const platformPerformance =
|
|
2126
|
+
const platformPerformance = getBrowserPerformance();
|
|
2127
2127
|
const timestampSource = platformPerformance === undefined
|
|
2128
2128
|
? dateTimestampSource
|
|
2129
2129
|
: {
|
|
@@ -3160,38 +3160,9 @@ var Sentry = (function (exports) {
|
|
|
3160
3160
|
if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(API_VERSION)) {
|
|
3161
3161
|
setHubOnCarrier(registry, new Hub());
|
|
3162
3162
|
}
|
|
3163
|
-
// Prefer domains over global if they are there (applicable only to Node environment)
|
|
3164
|
-
if (isNodeEnv()) {
|
|
3165
|
-
return getHubFromActiveDomain(registry);
|
|
3166
|
-
}
|
|
3167
3163
|
// Return hub that lives on a global object
|
|
3168
3164
|
return getHubFromCarrier(registry);
|
|
3169
3165
|
}
|
|
3170
|
-
/**
|
|
3171
|
-
* Try to read the hub from an active domain, and fallback to the registry if one doesn't exist
|
|
3172
|
-
* @returns discovered hub
|
|
3173
|
-
*/
|
|
3174
|
-
function getHubFromActiveDomain(registry) {
|
|
3175
|
-
try {
|
|
3176
|
-
const sentry = getMainCarrier().__SENTRY__;
|
|
3177
|
-
const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
|
|
3178
|
-
// If there's no active domain, just return global hub
|
|
3179
|
-
if (!activeDomain) {
|
|
3180
|
-
return getHubFromCarrier(registry);
|
|
3181
|
-
}
|
|
3182
|
-
// If there's no hub on current domain, or it's an old API, assign a new one
|
|
3183
|
-
if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(API_VERSION)) {
|
|
3184
|
-
const registryHubTopStack = getHubFromCarrier(registry).getStackTop();
|
|
3185
|
-
setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, Scope.clone(registryHubTopStack.scope)));
|
|
3186
|
-
}
|
|
3187
|
-
// Return hub that lives on a domain
|
|
3188
|
-
return getHubFromCarrier(activeDomain);
|
|
3189
|
-
}
|
|
3190
|
-
catch (_Oo) {
|
|
3191
|
-
// Return hub that lives on a global object
|
|
3192
|
-
return getHubFromCarrier(registry);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
3166
|
/**
|
|
3196
3167
|
* This will tell whether a carrier has a hub on it or not
|
|
3197
3168
|
* @param carrier object
|
|
@@ -3820,6 +3791,11 @@ var Sentry = (function (exports) {
|
|
|
3820
3791
|
result = finalScope.applyToEvent(prepared, hint);
|
|
3821
3792
|
}
|
|
3822
3793
|
return result.then(evt => {
|
|
3794
|
+
if (evt) {
|
|
3795
|
+
// TODO this is more of the hack trying to solve https://github.com/getsentry/sentry-javascript/issues/2809
|
|
3796
|
+
// it is only attached as extra data to the event if the event somehow skips being normalized
|
|
3797
|
+
evt.sdkProcessingMetadata = Object.assign(Object.assign({}, evt.sdkProcessingMetadata), { normalizeDepth: normalize(normalizeDepth) });
|
|
3798
|
+
}
|
|
3823
3799
|
if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {
|
|
3824
3800
|
return this._normalizeEvent(evt, normalizeDepth);
|
|
3825
3801
|
}
|
|
@@ -4164,22 +4140,27 @@ var Sentry = (function (exports) {
|
|
|
4164
4140
|
const { transactionSampling } = event.sdkProcessingMetadata || {};
|
|
4165
4141
|
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
|
|
4166
4142
|
// TODO: Below is a temporary hack in order to debug a serialization error - see
|
|
4167
|
-
// https://github.com/getsentry/sentry-javascript/issues/2809
|
|
4168
|
-
// https://github.com/getsentry/sentry-javascript/pull/4425
|
|
4169
|
-
//
|
|
4143
|
+
// https://github.com/getsentry/sentry-javascript/issues/2809,
|
|
4144
|
+
// https://github.com/getsentry/sentry-javascript/pull/4425, and
|
|
4145
|
+
// https://github.com/getsentry/sentry-javascript/pull/4574.
|
|
4146
|
+
//
|
|
4147
|
+
// TL; DR: even though we normalize all events (which should prevent this), something is causing `JSON.stringify` to
|
|
4148
|
+
// throw a circular reference error.
|
|
4170
4149
|
//
|
|
4171
4150
|
// When it's time to remove it:
|
|
4172
4151
|
// 1. Delete everything between here and where the request object `req` is created, EXCEPT the line deleting
|
|
4173
4152
|
// `sdkProcessingMetadata`
|
|
4174
4153
|
// 2. Restore the original version of the request body, which is commented out
|
|
4175
|
-
// 3. Search for
|
|
4154
|
+
// 3. Search for either of the PR URLs above and pull out the companion hacks in the browser playwright tests and the
|
|
4155
|
+
// baseClient tests in this package
|
|
4176
4156
|
enhanceEventWithSdkInfo(event, api.metadata.sdk);
|
|
4177
4157
|
event.tags = event.tags || {};
|
|
4178
4158
|
event.extra = event.extra || {};
|
|
4179
4159
|
// In theory, all events should be marked as having gone through normalization and so
|
|
4180
|
-
// we should never set this tag
|
|
4160
|
+
// we should never set this tag/extra data
|
|
4181
4161
|
if (!(event.sdkProcessingMetadata && event.sdkProcessingMetadata.baseClientNormalized)) {
|
|
4182
4162
|
event.tags.skippedNormalization = true;
|
|
4163
|
+
event.extra.normalizeDepth = event.sdkProcessingMetadata ? event.sdkProcessingMetadata.normalizeDepth : 'unset';
|
|
4183
4164
|
}
|
|
4184
4165
|
// prevent this data from being sent to sentry
|
|
4185
4166
|
// TODO: This is NOT part of the hack - DO NOT DELETE
|
|
@@ -4261,7 +4242,7 @@ var Sentry = (function (exports) {
|
|
|
4261
4242
|
hub.bindClient(client);
|
|
4262
4243
|
}
|
|
4263
4244
|
|
|
4264
|
-
const SDK_VERSION = '6.17.
|
|
4245
|
+
const SDK_VERSION = '6.17.8';
|
|
4265
4246
|
|
|
4266
4247
|
let originalFunctionToString;
|
|
4267
4248
|
/** Patch toString calls to return proper name for wrapped functions */
|
|
@@ -4492,205 +4473,89 @@ var Sentry = (function (exports) {
|
|
|
4492
4473
|
InboundFilters: InboundFilters
|
|
4493
4474
|
});
|
|
4494
4475
|
|
|
4495
|
-
/**
|
|
4496
|
-
* This was originally forked from https://github.com/occ/TraceKit, but has since been
|
|
4497
|
-
* largely modified and is now maintained as part of Sentry JS SDK.
|
|
4498
|
-
*/
|
|
4499
4476
|
// global reference to slice
|
|
4500
4477
|
const UNKNOWN_FUNCTION = '?';
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
|
|
4511
|
-
const reactMinifiedRegexp = /Minified React error #\d+;/i;
|
|
4512
|
-
/** JSDoc */
|
|
4513
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
4514
|
-
function computeStackTrace(ex) {
|
|
4515
|
-
let stack = null;
|
|
4516
|
-
let popSize = 0;
|
|
4517
|
-
if (ex) {
|
|
4518
|
-
if (typeof ex.framesToPop === 'number') {
|
|
4519
|
-
popSize = ex.framesToPop;
|
|
4520
|
-
}
|
|
4521
|
-
else if (reactMinifiedRegexp.test(ex.message)) {
|
|
4522
|
-
popSize = 1;
|
|
4523
|
-
}
|
|
4524
|
-
}
|
|
4525
|
-
try {
|
|
4526
|
-
// This must be tried first because Opera 10 *destroys*
|
|
4527
|
-
// its stacktrace property if you try to access the stack
|
|
4528
|
-
// property first!!
|
|
4529
|
-
stack = computeStackTraceFromStacktraceProp(ex);
|
|
4530
|
-
if (stack) {
|
|
4531
|
-
return popFrames(stack, popSize);
|
|
4532
|
-
}
|
|
4533
|
-
}
|
|
4534
|
-
catch (e) {
|
|
4535
|
-
// no-empty
|
|
4536
|
-
}
|
|
4537
|
-
try {
|
|
4538
|
-
stack = computeStackTraceFromStackProp(ex);
|
|
4539
|
-
if (stack) {
|
|
4540
|
-
return popFrames(stack, popSize);
|
|
4541
|
-
}
|
|
4478
|
+
function createFrame(filename, func, lineno, colno) {
|
|
4479
|
+
const frame = {
|
|
4480
|
+
filename,
|
|
4481
|
+
function: func,
|
|
4482
|
+
// All browser frames are considered in_app
|
|
4483
|
+
in_app: true,
|
|
4484
|
+
};
|
|
4485
|
+
if (lineno !== undefined) {
|
|
4486
|
+
frame.lineno = lineno;
|
|
4542
4487
|
}
|
|
4543
|
-
|
|
4544
|
-
|
|
4488
|
+
if (colno !== undefined) {
|
|
4489
|
+
frame.colno = colno;
|
|
4545
4490
|
}
|
|
4546
|
-
return
|
|
4547
|
-
message: extractMessage(ex),
|
|
4548
|
-
name: ex && ex.name,
|
|
4549
|
-
stack: [],
|
|
4550
|
-
failed: true,
|
|
4551
|
-
};
|
|
4491
|
+
return frame;
|
|
4552
4492
|
}
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
let parts;
|
|
4564
|
-
let element;
|
|
4565
|
-
for (let i = 0; i < lines.length; ++i) {
|
|
4566
|
-
if ((parts = chrome.exec(lines[i]))) {
|
|
4567
|
-
const isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
|
|
4568
|
-
isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
|
|
4569
|
-
if (isEval && (submatch = chromeEval.exec(parts[2]))) {
|
|
4493
|
+
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
|
|
4494
|
+
const chromeRegex = /^\s*at (?:(.*?) ?\((?:address at )?)?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
4495
|
+
const chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
|
|
4496
|
+
const chrome = line => {
|
|
4497
|
+
const parts = chromeRegex.exec(line);
|
|
4498
|
+
if (parts) {
|
|
4499
|
+
const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
|
|
4500
|
+
if (isEval) {
|
|
4501
|
+
const subMatch = chromeEvalRegex.exec(parts[2]);
|
|
4502
|
+
if (subMatch) {
|
|
4570
4503
|
// throw out eval line/column and use top-most line/column number
|
|
4571
|
-
parts[2] =
|
|
4572
|
-
parts[3] =
|
|
4573
|
-
parts[4] =
|
|
4504
|
+
parts[2] = subMatch[1]; // url
|
|
4505
|
+
parts[3] = subMatch[2]; // line
|
|
4506
|
+
parts[4] = subMatch[3]; // column
|
|
4574
4507
|
}
|
|
4575
|
-
// Arpad: Working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `
|
|
4576
|
-
// prefix here seems like the quickest solution for now.
|
|
4577
|
-
let url = parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2];
|
|
4578
|
-
// Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
|
|
4579
|
-
// would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
|
|
4580
|
-
let func = parts[1] || UNKNOWN_FUNCTION;
|
|
4581
|
-
[func, url] = extractSafariExtensionDetails(func, url);
|
|
4582
|
-
element = {
|
|
4583
|
-
url,
|
|
4584
|
-
func,
|
|
4585
|
-
args: isNative ? [parts[2]] : [],
|
|
4586
|
-
line: parts[3] ? +parts[3] : null,
|
|
4587
|
-
column: parts[4] ? +parts[4] : null,
|
|
4588
|
-
};
|
|
4589
|
-
}
|
|
4590
|
-
else if ((parts = winjs.exec(lines[i]))) {
|
|
4591
|
-
element = {
|
|
4592
|
-
url: parts[2],
|
|
4593
|
-
func: parts[1] || UNKNOWN_FUNCTION,
|
|
4594
|
-
args: [],
|
|
4595
|
-
line: +parts[3],
|
|
4596
|
-
column: parts[4] ? +parts[4] : null,
|
|
4597
|
-
};
|
|
4598
4508
|
}
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4509
|
+
// Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
|
|
4510
|
+
// would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
|
|
4511
|
+
const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
|
|
4512
|
+
return createFrame(filename, func, parts[3] ? +parts[3] : undefined, parts[4] ? +parts[4] : undefined);
|
|
4513
|
+
}
|
|
4514
|
+
return;
|
|
4515
|
+
};
|
|
4516
|
+
// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
|
|
4517
|
+
// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
|
|
4518
|
+
// We need this specific case for now because we want no other regex to match.
|
|
4519
|
+
const geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|capacitor).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
|
|
4520
|
+
const geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
|
4521
|
+
const gecko = line => {
|
|
4522
|
+
const parts = geckoREgex.exec(line);
|
|
4523
|
+
if (parts) {
|
|
4524
|
+
const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
|
|
4525
|
+
if (isEval) {
|
|
4526
|
+
const subMatch = geckoEvalRegex.exec(parts[3]);
|
|
4527
|
+
if (subMatch) {
|
|
4602
4528
|
// throw out eval line/column and use top-most line number
|
|
4603
4529
|
parts[1] = parts[1] || `eval`;
|
|
4604
|
-
parts[3] =
|
|
4605
|
-
parts[4] =
|
|
4530
|
+
parts[3] = subMatch[1];
|
|
4531
|
+
parts[4] = subMatch[2];
|
|
4606
4532
|
parts[5] = ''; // no column when eval
|
|
4607
4533
|
}
|
|
4608
|
-
else if (i === 0 && !parts[5] && ex.columnNumber !== void 0) {
|
|
4609
|
-
// FireFox uses this awesome columnNumber property for its top frame
|
|
4610
|
-
// Also note, Firefox's column number is 0-based and everything else expects 1-based,
|
|
4611
|
-
// so adding 1
|
|
4612
|
-
// NOTE: this hack doesn't work if top-most frame is eval
|
|
4613
|
-
stack[0].column = ex.columnNumber + 1;
|
|
4614
|
-
}
|
|
4615
|
-
let url = parts[3];
|
|
4616
|
-
let func = parts[1] || UNKNOWN_FUNCTION;
|
|
4617
|
-
[func, url] = extractSafariExtensionDetails(func, url);
|
|
4618
|
-
element = {
|
|
4619
|
-
url,
|
|
4620
|
-
func,
|
|
4621
|
-
args: parts[2] ? parts[2].split(',') : [],
|
|
4622
|
-
line: parts[4] ? +parts[4] : null,
|
|
4623
|
-
column: parts[5] ? +parts[5] : null,
|
|
4624
|
-
};
|
|
4625
|
-
}
|
|
4626
|
-
else {
|
|
4627
|
-
continue;
|
|
4628
|
-
}
|
|
4629
|
-
if (!element.func && element.line) {
|
|
4630
|
-
element.func = UNKNOWN_FUNCTION;
|
|
4631
|
-
}
|
|
4632
|
-
stack.push(element);
|
|
4633
|
-
}
|
|
4634
|
-
if (!stack.length) {
|
|
4635
|
-
return null;
|
|
4636
|
-
}
|
|
4637
|
-
return {
|
|
4638
|
-
message: extractMessage(ex),
|
|
4639
|
-
name: ex.name,
|
|
4640
|
-
stack,
|
|
4641
|
-
};
|
|
4642
|
-
}
|
|
4643
|
-
/** JSDoc */
|
|
4644
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4645
|
-
function computeStackTraceFromStacktraceProp(ex) {
|
|
4646
|
-
if (!ex || !ex.stacktrace) {
|
|
4647
|
-
return null;
|
|
4648
|
-
}
|
|
4649
|
-
// Access and store the stacktrace property before doing ANYTHING
|
|
4650
|
-
// else to it because Opera is not very good at providing it
|
|
4651
|
-
// reliably in other circumstances.
|
|
4652
|
-
const stacktrace = ex.stacktrace;
|
|
4653
|
-
const opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
|
|
4654
|
-
const opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\((.*)\))? in (.*):\s*$/i;
|
|
4655
|
-
const lines = stacktrace.split('\n');
|
|
4656
|
-
const stack = [];
|
|
4657
|
-
let parts;
|
|
4658
|
-
for (let line = 0; line < lines.length; line += 2) {
|
|
4659
|
-
let element = null;
|
|
4660
|
-
if ((parts = opera10Regex.exec(lines[line]))) {
|
|
4661
|
-
element = {
|
|
4662
|
-
url: parts[2],
|
|
4663
|
-
func: parts[3],
|
|
4664
|
-
args: [],
|
|
4665
|
-
line: +parts[1],
|
|
4666
|
-
column: null,
|
|
4667
|
-
};
|
|
4668
|
-
}
|
|
4669
|
-
else if ((parts = opera11Regex.exec(lines[line]))) {
|
|
4670
|
-
element = {
|
|
4671
|
-
url: parts[6],
|
|
4672
|
-
func: parts[3] || parts[4],
|
|
4673
|
-
args: parts[5] ? parts[5].split(',') : [],
|
|
4674
|
-
line: +parts[1],
|
|
4675
|
-
column: +parts[2],
|
|
4676
|
-
};
|
|
4677
|
-
}
|
|
4678
|
-
if (element) {
|
|
4679
|
-
if (!element.func && element.line) {
|
|
4680
|
-
element.func = UNKNOWN_FUNCTION;
|
|
4681
|
-
}
|
|
4682
|
-
stack.push(element);
|
|
4683
4534
|
}
|
|
4535
|
+
let filename = parts[3];
|
|
4536
|
+
let func = parts[1] || UNKNOWN_FUNCTION;
|
|
4537
|
+
[func, filename] = extractSafariExtensionDetails(func, filename);
|
|
4538
|
+
return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);
|
|
4684
4539
|
}
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
}
|
|
4540
|
+
return;
|
|
4541
|
+
};
|
|
4542
|
+
const winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
4543
|
+
const winjs = line => {
|
|
4544
|
+
const parts = winjsRegex.exec(line);
|
|
4545
|
+
return parts
|
|
4546
|
+
? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)
|
|
4547
|
+
: undefined;
|
|
4548
|
+
};
|
|
4549
|
+
const opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
|
|
4550
|
+
const opera10 = line => {
|
|
4551
|
+
const parts = opera10Regex.exec(line);
|
|
4552
|
+
return parts ? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : undefined;
|
|
4553
|
+
};
|
|
4554
|
+
const opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
|
|
4555
|
+
const opera11 = line => {
|
|
4556
|
+
const parts = opera11Regex.exec(line);
|
|
4557
|
+
return parts ? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
|
|
4558
|
+
};
|
|
4694
4559
|
/**
|
|
4695
4560
|
* Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.
|
|
4696
4561
|
* What it means, is that instead of format like:
|
|
@@ -4708,56 +4573,31 @@ var Sentry = (function (exports) {
|
|
|
4708
4573
|
*
|
|
4709
4574
|
* Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.
|
|
4710
4575
|
* This function is extracted so that we can use it in both places without duplicating the logic.
|
|
4711
|
-
*
|
|
4576
|
+
* Unfortunately "just" changing RegExp is too complicated now and making it pass all tests
|
|
4712
4577
|
* and fix this case seems like an impossible, or at least way too time-consuming task.
|
|
4713
4578
|
*/
|
|
4714
|
-
const extractSafariExtensionDetails = (func,
|
|
4579
|
+
const extractSafariExtensionDetails = (func, filename) => {
|
|
4715
4580
|
const isSafariExtension = func.indexOf('safari-extension') !== -1;
|
|
4716
4581
|
const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;
|
|
4717
4582
|
return isSafariExtension || isSafariWebExtension
|
|
4718
4583
|
? [
|
|
4719
4584
|
func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,
|
|
4720
|
-
isSafariExtension ? `safari-extension:${
|
|
4585
|
+
isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,
|
|
4721
4586
|
]
|
|
4722
|
-
: [func,
|
|
4723
|
-
};
|
|
4724
|
-
/** Remove N number of frames from the stack */
|
|
4725
|
-
function popFrames(stacktrace, popSize) {
|
|
4726
|
-
try {
|
|
4727
|
-
return Object.assign(Object.assign({}, stacktrace), { stack: stacktrace.stack.slice(popSize) });
|
|
4728
|
-
}
|
|
4729
|
-
catch (e) {
|
|
4730
|
-
return stacktrace;
|
|
4731
|
-
}
|
|
4732
|
-
}
|
|
4733
|
-
/**
|
|
4734
|
-
* There are cases where stacktrace.message is an Event object
|
|
4735
|
-
* https://github.com/getsentry/sentry-javascript/issues/1949
|
|
4736
|
-
* In this specific case we try to extract stacktrace.message.error.message
|
|
4737
|
-
*/
|
|
4738
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4739
|
-
function extractMessage(ex) {
|
|
4740
|
-
const message = ex && ex.message;
|
|
4741
|
-
if (!message) {
|
|
4742
|
-
return 'No error message';
|
|
4743
|
-
}
|
|
4744
|
-
if (message.error && typeof message.error.message === 'string') {
|
|
4745
|
-
return message.error.message;
|
|
4746
|
-
}
|
|
4747
|
-
return message;
|
|
4748
|
-
}
|
|
4587
|
+
: [func, filename];
|
|
4588
|
+
};
|
|
4749
4589
|
|
|
4750
|
-
const STACKTRACE_LIMIT = 50;
|
|
4751
4590
|
/**
|
|
4752
4591
|
* This function creates an exception from an TraceKitStackTrace
|
|
4753
4592
|
* @param stacktrace TraceKitStackTrace that will be converted to an exception
|
|
4754
4593
|
* @hidden
|
|
4755
4594
|
*/
|
|
4756
|
-
function
|
|
4757
|
-
|
|
4595
|
+
function exceptionFromError(ex) {
|
|
4596
|
+
// Get the frames first since Opera can lose the stack if we touch anything else first
|
|
4597
|
+
const frames = parseStackFrames(ex);
|
|
4758
4598
|
const exception = {
|
|
4759
|
-
type:
|
|
4760
|
-
value:
|
|
4599
|
+
type: ex && ex.name,
|
|
4600
|
+
value: extractMessage(ex),
|
|
4761
4601
|
};
|
|
4762
4602
|
if (frames && frames.length) {
|
|
4763
4603
|
exception.stacktrace = { frames };
|
|
@@ -4785,10 +4625,8 @@ var Sentry = (function (exports) {
|
|
|
4785
4625
|
},
|
|
4786
4626
|
};
|
|
4787
4627
|
if (syntheticException) {
|
|
4788
|
-
const stacktrace = computeStackTrace(syntheticException);
|
|
4789
|
-
const frames = prepareFramesForEvent(stacktrace.stack);
|
|
4790
4628
|
event.stacktrace = {
|
|
4791
|
-
frames,
|
|
4629
|
+
frames: parseStackFrames(syntheticException),
|
|
4792
4630
|
};
|
|
4793
4631
|
}
|
|
4794
4632
|
return event;
|
|
@@ -4796,43 +4634,57 @@ var Sentry = (function (exports) {
|
|
|
4796
4634
|
/**
|
|
4797
4635
|
* @hidden
|
|
4798
4636
|
*/
|
|
4799
|
-
function
|
|
4800
|
-
const exception = exceptionFromStacktrace(stacktrace);
|
|
4637
|
+
function eventFromError(ex) {
|
|
4801
4638
|
return {
|
|
4802
4639
|
exception: {
|
|
4803
|
-
values: [
|
|
4640
|
+
values: [exceptionFromError(ex)],
|
|
4804
4641
|
},
|
|
4805
4642
|
};
|
|
4806
4643
|
}
|
|
4644
|
+
/** Parses stack frames from an error */
|
|
4645
|
+
function parseStackFrames(ex) {
|
|
4646
|
+
// Access and store the stacktrace property before doing ANYTHING
|
|
4647
|
+
// else to it because Opera is not very good at providing it
|
|
4648
|
+
// reliably in other circumstances.
|
|
4649
|
+
const stacktrace = ex.stacktrace || ex.stack || '';
|
|
4650
|
+
const popSize = getPopSize(ex);
|
|
4651
|
+
try {
|
|
4652
|
+
// The order of the parsers in important
|
|
4653
|
+
return createStackParser(opera10, opera11, chrome, winjs, gecko)(stacktrace, popSize);
|
|
4654
|
+
}
|
|
4655
|
+
catch (e) {
|
|
4656
|
+
// no-empty
|
|
4657
|
+
}
|
|
4658
|
+
return [];
|
|
4659
|
+
}
|
|
4660
|
+
// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
|
|
4661
|
+
const reactMinifiedRegexp = /Minified React error #\d+;/i;
|
|
4662
|
+
function getPopSize(ex) {
|
|
4663
|
+
if (ex) {
|
|
4664
|
+
if (typeof ex.framesToPop === 'number') {
|
|
4665
|
+
return ex.framesToPop;
|
|
4666
|
+
}
|
|
4667
|
+
if (reactMinifiedRegexp.test(ex.message)) {
|
|
4668
|
+
return 1;
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
return 0;
|
|
4672
|
+
}
|
|
4807
4673
|
/**
|
|
4808
|
-
*
|
|
4674
|
+
* There are cases where stacktrace.message is an Event object
|
|
4675
|
+
* https://github.com/getsentry/sentry-javascript/issues/1949
|
|
4676
|
+
* In this specific case we try to extract stacktrace.message.error.message
|
|
4809
4677
|
*/
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
const firstFrameFunction = localStack[0].func || '';
|
|
4816
|
-
const lastFrameFunction = localStack[localStack.length - 1].func || '';
|
|
4817
|
-
// If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
|
|
4818
|
-
if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
|
|
4819
|
-
localStack = localStack.slice(1);
|
|
4678
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4679
|
+
function extractMessage(ex) {
|
|
4680
|
+
const message = ex && ex.message;
|
|
4681
|
+
if (!message) {
|
|
4682
|
+
return 'No error message';
|
|
4820
4683
|
}
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
localStack = localStack.slice(0, -1);
|
|
4684
|
+
if (message.error && typeof message.error.message === 'string') {
|
|
4685
|
+
return message.error.message;
|
|
4824
4686
|
}
|
|
4825
|
-
|
|
4826
|
-
return localStack
|
|
4827
|
-
.slice(0, STACKTRACE_LIMIT)
|
|
4828
|
-
.map((frame) => ({
|
|
4829
|
-
colno: frame.column === null ? undefined : frame.column,
|
|
4830
|
-
filename: frame.url || localStack[0].url,
|
|
4831
|
-
function: frame.func || '?',
|
|
4832
|
-
in_app: true,
|
|
4833
|
-
lineno: frame.line === null ? undefined : frame.line,
|
|
4834
|
-
}))
|
|
4835
|
-
.reverse();
|
|
4687
|
+
return message;
|
|
4836
4688
|
}
|
|
4837
4689
|
|
|
4838
4690
|
/**
|
|
@@ -4874,10 +4726,7 @@ var Sentry = (function (exports) {
|
|
|
4874
4726
|
if (isErrorEvent(exception) && exception.error) {
|
|
4875
4727
|
// If it is an ErrorEvent with `error` property, extract it to get actual Error
|
|
4876
4728
|
const errorEvent = exception;
|
|
4877
|
-
|
|
4878
|
-
exception = errorEvent.error;
|
|
4879
|
-
event = eventFromStacktrace(computeStackTrace(exception));
|
|
4880
|
-
return event;
|
|
4729
|
+
return eventFromError(errorEvent.error);
|
|
4881
4730
|
}
|
|
4882
4731
|
// If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
|
|
4883
4732
|
// and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
|
|
@@ -4889,7 +4738,7 @@ var Sentry = (function (exports) {
|
|
|
4889
4738
|
if (isDOMError(exception) || isDOMException(exception)) {
|
|
4890
4739
|
const domException = exception;
|
|
4891
4740
|
if ('stack' in exception) {
|
|
4892
|
-
event =
|
|
4741
|
+
event = eventFromError(exception);
|
|
4893
4742
|
}
|
|
4894
4743
|
else {
|
|
4895
4744
|
const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');
|
|
@@ -4904,8 +4753,7 @@ var Sentry = (function (exports) {
|
|
|
4904
4753
|
}
|
|
4905
4754
|
if (isError(exception)) {
|
|
4906
4755
|
// we have a real Error object, do nothing
|
|
4907
|
-
|
|
4908
|
-
return event;
|
|
4756
|
+
return eventFromError(exception);
|
|
4909
4757
|
}
|
|
4910
4758
|
if (isPlainObject(exception) || isEvent(exception)) {
|
|
4911
4759
|
// If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
|
|
@@ -4942,10 +4790,8 @@ var Sentry = (function (exports) {
|
|
|
4942
4790
|
message: input,
|
|
4943
4791
|
};
|
|
4944
4792
|
if (options.attachStacktrace && syntheticException) {
|
|
4945
|
-
const stacktrace = computeStackTrace(syntheticException);
|
|
4946
|
-
const frames = prepareFramesForEvent(stacktrace.stack);
|
|
4947
4793
|
event.stacktrace = {
|
|
4948
|
-
frames,
|
|
4794
|
+
frames: parseStackFrames(syntheticException),
|
|
4949
4795
|
};
|
|
4950
4796
|
}
|
|
4951
4797
|
return event;
|
|
@@ -6212,8 +6058,7 @@ var Sentry = (function (exports) {
|
|
|
6212
6058
|
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
|
|
6213
6059
|
return stack;
|
|
6214
6060
|
}
|
|
6215
|
-
const
|
|
6216
|
-
const exception = exceptionFromStacktrace(stacktrace);
|
|
6061
|
+
const exception = exceptionFromError(error[key]);
|
|
6217
6062
|
return _walkErrorTree(limit, error[key], key, [exception, ...stack]);
|
|
6218
6063
|
}
|
|
6219
6064
|
|