@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.
Files changed (45) hide show
  1. package/build/bundle.es6.js +206 -361
  2. package/build/bundle.es6.js.map +1 -1
  3. package/build/bundle.es6.min.js +2 -2
  4. package/build/bundle.es6.min.js.map +1 -1
  5. package/build/bundle.js +250 -375
  6. package/build/bundle.js.map +1 -1
  7. package/build/bundle.min.js +2 -2
  8. package/build/bundle.min.js.map +1 -1
  9. package/dist/eventbuilder.d.ts.map +1 -1
  10. package/dist/eventbuilder.js +4 -11
  11. package/dist/eventbuilder.js.map +1 -1
  12. package/dist/integrations/linkederrors.d.ts.map +1 -1
  13. package/dist/integrations/linkederrors.js +1 -3
  14. package/dist/integrations/linkederrors.js.map +1 -1
  15. package/dist/parsers.d.ts +7 -7
  16. package/dist/parsers.d.ts.map +1 -1
  17. package/dist/parsers.js +52 -40
  18. package/dist/parsers.js.map +1 -1
  19. package/dist/stack-parsers.d.ts +7 -0
  20. package/dist/stack-parsers.d.ts.map +1 -0
  21. package/dist/stack-parsers.js +117 -0
  22. package/dist/stack-parsers.js.map +1 -0
  23. package/esm/eventbuilder.d.ts.map +1 -1
  24. package/esm/eventbuilder.js +5 -12
  25. package/esm/eventbuilder.js.map +1 -1
  26. package/esm/integrations/linkederrors.d.ts.map +1 -1
  27. package/esm/integrations/linkederrors.js +2 -4
  28. package/esm/integrations/linkederrors.js.map +1 -1
  29. package/esm/parsers.d.ts +7 -7
  30. package/esm/parsers.d.ts.map +1 -1
  31. package/esm/parsers.js +50 -38
  32. package/esm/parsers.js.map +1 -1
  33. package/esm/stack-parsers.d.ts +7 -0
  34. package/esm/stack-parsers.d.ts.map +1 -0
  35. package/esm/stack-parsers.js +116 -0
  36. package/esm/stack-parsers.js.map +1 -0
  37. package/package.json +4 -7
  38. package/dist/tracekit.d.ts +0 -38
  39. package/dist/tracekit.d.ts.map +0 -1
  40. package/dist/tracekit.js +0 -259
  41. package/dist/tracekit.js.map +0 -1
  42. package/esm/tracekit.d.ts +0 -38
  43. package/esm/tracekit.d.ts.map +0 -1
  44. package/esm/tracekit.js +0 -257
  45. package/esm/tracekit.js.map +0 -1
package/build/bundle.js CHANGED
@@ -1,29 +1,31 @@
1
- /*! @sentry/browser 6.17.5 (82779c3) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.17.8 (db493a0) | https://github.com/getsentry/sentry-javascript */
2
2
  var Sentry = (function (exports) {
3
3
  /*! *****************************************************************************
4
- Copyright (c) Microsoft Corporation. All rights reserved.
5
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
6
- this file except in compliance with the License. You may obtain a copy of the
7
- License at http://www.apache.org/licenses/LICENSE-2.0
4
+ Copyright (c) Microsoft Corporation.
8
5
 
9
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
11
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
12
- MERCHANTABLITY OR NON-INFRINGEMENT.
6
+ Permission to use, copy, modify, and/or distribute this software for any
7
+ purpose with or without fee is hereby granted.
13
8
 
14
- See the Apache Version 2.0 License for specific language governing permissions
15
- and limitations under the License.
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
16
16
  ***************************************************************************** */
17
17
  /* global Reflect, Promise */
18
18
 
19
19
  var extendStatics = function(d, b) {
20
20
  extendStatics = Object.setPrototypeOf ||
21
21
  ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
22
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
22
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
23
23
  return extendStatics(d, b);
24
24
  };
25
25
 
26
26
  function __extends(d, b) {
27
+ if (typeof b !== "function" && b !== null)
28
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
27
29
  extendStatics(d, b);
28
30
  function __() { this.constructor = d; }
29
31
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
@@ -41,14 +43,15 @@ var Sentry = (function (exports) {
41
43
  };
42
44
 
43
45
  function __values(o) {
44
- var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
46
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
45
47
  if (m) return m.call(o);
46
- return {
48
+ if (o && typeof o.length === "number") return {
47
49
  next: function () {
48
50
  if (o && i >= o.length) o = void 0;
49
51
  return { value: o && o[i++], done: !o };
50
52
  }
51
53
  };
54
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
52
55
  }
53
56
 
54
57
  function __read(o, n) {
@@ -68,6 +71,7 @@ var Sentry = (function (exports) {
68
71
  return ar;
69
72
  }
70
73
 
74
+ /** @deprecated */
71
75
  function __spread() {
72
76
  for (var ar = [], i = 0; i < arguments.length; i++)
73
77
  ar = ar.concat(__read(arguments[i]));
@@ -123,41 +127,7 @@ var Sentry = (function (exports) {
123
127
  * @returns true if this is a debug build
124
128
  */
125
129
  function isDebugBuild() {
126
- return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !__SENTRY_BROWSER_BUNDLE__;
127
- }
128
- /**
129
- * Figures out if we're building a browser bundle.
130
- *
131
- * @returns true if this is a browser bundle build.
132
- */
133
- function isBrowserBundle() {
134
- return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
135
- }
136
-
137
- /**
138
- * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
139
- * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
140
- */
141
- /**
142
- * Checks whether we're in the Node.js or Browser environment
143
- *
144
- * @returns Answer to given question
145
- */
146
- function isNodeEnv() {
147
- // explicitly check for browser bundles as those can be optimized statically
148
- // by terser/rollup.
149
- return (!isBrowserBundle() &&
150
- Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]');
151
- }
152
- /**
153
- * Requires a module which is protected against bundler minification.
154
- *
155
- * @param request The module path to resolve
156
- */
157
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
158
- function dynamicRequire(mod, request) {
159
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
160
- return mod.require(request);
130
+ return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !true;
161
131
  }
162
132
 
163
133
  /**
@@ -171,9 +141,7 @@ var Sentry = (function (exports) {
171
141
  * @returns Global scope object
172
142
  */
173
143
  function getGlobalObject() {
174
- return (isNodeEnv()
175
- ? global
176
- : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
144
+ return ( typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
177
145
  ? window // eslint-disable-line no-restricted-globals
178
146
  : typeof self !== 'undefined'
179
147
  ? self
@@ -695,6 +663,79 @@ var Sentry = (function (exports) {
695
663
  return [memoize, unmemoize];
696
664
  }
697
665
 
666
+ var STACKTRACE_LIMIT = 50;
667
+ /**
668
+ * Creates a stack parser with the supplied line parsers
669
+ *
670
+ * StackFrames are returned in the correct order for Sentry Exception
671
+ * frames and with Sentry SDK internal frames removed from the top and bottom
672
+ *
673
+ * */
674
+ function createStackParser() {
675
+ var parsers = [];
676
+ for (var _i = 0; _i < arguments.length; _i++) {
677
+ parsers[_i] = arguments[_i];
678
+ }
679
+ return function (stack, skipFirst) {
680
+ var e_1, _a, e_2, _b;
681
+ if (skipFirst === void 0) { skipFirst = 0; }
682
+ var frames = [];
683
+ try {
684
+ for (var _c = __values(stack.split('\n').slice(skipFirst)), _d = _c.next(); !_d.done; _d = _c.next()) {
685
+ var line = _d.value;
686
+ try {
687
+ for (var parsers_1 = (e_2 = void 0, __values(parsers)), parsers_1_1 = parsers_1.next(); !parsers_1_1.done; parsers_1_1 = parsers_1.next()) {
688
+ var parser = parsers_1_1.value;
689
+ var frame = parser(line);
690
+ if (frame) {
691
+ frames.push(frame);
692
+ break;
693
+ }
694
+ }
695
+ }
696
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
697
+ finally {
698
+ try {
699
+ if (parsers_1_1 && !parsers_1_1.done && (_b = parsers_1.return)) _b.call(parsers_1);
700
+ }
701
+ finally { if (e_2) throw e_2.error; }
702
+ }
703
+ }
704
+ }
705
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
706
+ finally {
707
+ try {
708
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
709
+ }
710
+ finally { if (e_1) throw e_1.error; }
711
+ }
712
+ return stripSentryFramesAndReverse(frames);
713
+ };
714
+ }
715
+ /**
716
+ * @hidden
717
+ */
718
+ function stripSentryFramesAndReverse(stack) {
719
+ if (!stack.length) {
720
+ return [];
721
+ }
722
+ var localStack = stack;
723
+ var firstFrameFunction = localStack[0].function || '';
724
+ var lastFrameFunction = localStack[localStack.length - 1].function || '';
725
+ // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
726
+ if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
727
+ localStack = localStack.slice(1);
728
+ }
729
+ // 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)
730
+ if (lastFrameFunction.indexOf('sentryWrapped') !== -1) {
731
+ localStack = localStack.slice(0, -1);
732
+ }
733
+ // The frame where the crash happened, should be the last entry in the array
734
+ return localStack
735
+ .slice(0, STACKTRACE_LIMIT)
736
+ .map(function (frame) { return (__assign(__assign({}, frame), { filename: frame.filename || localStack[0].filename, function: frame.function || '?' })); })
737
+ .reverse();
738
+ }
698
739
  var defaultFunctionName = '<anonymous>';
699
740
  /**
700
741
  * Safely extract function name from itself
@@ -800,16 +841,18 @@ var Sentry = (function (exports) {
800
841
  source[name] = wrapped;
801
842
  }
802
843
  /**
803
- * Defines a non enumerable property. This creates a non enumerable property on an object.
844
+ * Defines a non-enumerable property on the given object.
804
845
  *
805
- * @param func The function to set a property to
806
- * @param name the name of the special sentry property
807
- * @param value the property to define
846
+ * @param obj The object on which to set the property
847
+ * @param name The name of the property to be set
848
+ * @param value The value to which to set the property
808
849
  */
809
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
810
- function addNonEnumerableProperty(func, name, value) {
811
- Object.defineProperty(func, name, {
850
+ function addNonEnumerableProperty(obj, name, value) {
851
+ Object.defineProperty(obj, name, {
852
+ // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
812
853
  value: value,
854
+ writable: true,
855
+ configurable: true,
813
856
  });
814
857
  }
815
858
  /**
@@ -1332,7 +1375,7 @@ var Sentry = (function (exports) {
1332
1375
  if (!(level in global$2.console)) {
1333
1376
  return;
1334
1377
  }
1335
- fill(global$2.console, level, function (originalConsoleLevel) {
1378
+ fill(global$2.console, level, function (originalConsoleMethod) {
1336
1379
  return function () {
1337
1380
  var args = [];
1338
1381
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -1340,8 +1383,8 @@ var Sentry = (function (exports) {
1340
1383
  }
1341
1384
  triggerHandlers('console', { args: args, level: level });
1342
1385
  // this fails for some browsers. :(
1343
- if (originalConsoleLevel) {
1344
- Function.prototype.apply.call(originalConsoleLevel, global$2.console, args);
1386
+ if (originalConsoleMethod) {
1387
+ originalConsoleMethod.apply(global$2.console, args);
1345
1388
  }
1346
1389
  };
1347
1390
  });
@@ -2264,23 +2307,10 @@ var Sentry = (function (exports) {
2264
2307
  timeOrigin: timeOrigin,
2265
2308
  };
2266
2309
  }
2267
- /**
2268
- * Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't
2269
- * implement the API.
2270
- */
2271
- function getNodePerformance() {
2272
- try {
2273
- var perfHooks = dynamicRequire(module, 'perf_hooks');
2274
- return perfHooks.performance;
2275
- }
2276
- catch (_) {
2277
- return undefined;
2278
- }
2279
- }
2280
2310
  /**
2281
2311
  * The Performance API implementation for the current platform, if available.
2282
2312
  */
2283
- var platformPerformance = isNodeEnv() ? getNodePerformance() : getBrowserPerformance();
2313
+ var platformPerformance = getBrowserPerformance();
2284
2314
  var timestampSource = platformPerformance === undefined
2285
2315
  ? dateTimestampSource
2286
2316
  : {
@@ -3339,38 +3369,9 @@ var Sentry = (function (exports) {
3339
3369
  if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(API_VERSION)) {
3340
3370
  setHubOnCarrier(registry, new Hub());
3341
3371
  }
3342
- // Prefer domains over global if they are there (applicable only to Node environment)
3343
- if (isNodeEnv()) {
3344
- return getHubFromActiveDomain(registry);
3345
- }
3346
3372
  // Return hub that lives on a global object
3347
3373
  return getHubFromCarrier(registry);
3348
3374
  }
3349
- /**
3350
- * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist
3351
- * @returns discovered hub
3352
- */
3353
- function getHubFromActiveDomain(registry) {
3354
- try {
3355
- var sentry = getMainCarrier().__SENTRY__;
3356
- var activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
3357
- // If there's no active domain, just return global hub
3358
- if (!activeDomain) {
3359
- return getHubFromCarrier(registry);
3360
- }
3361
- // If there's no hub on current domain, or it's an old API, assign a new one
3362
- if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(API_VERSION)) {
3363
- var registryHubTopStack = getHubFromCarrier(registry).getStackTop();
3364
- setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, Scope.clone(registryHubTopStack.scope)));
3365
- }
3366
- // Return hub that lives on a domain
3367
- return getHubFromCarrier(activeDomain);
3368
- }
3369
- catch (_Oo) {
3370
- // Return hub that lives on a global object
3371
- return getHubFromCarrier(registry);
3372
- }
3373
- }
3374
3375
  /**
3375
3376
  * This will tell whether a carrier has a hub on it or not
3376
3377
  * @param carrier object
@@ -4017,6 +4018,11 @@ var Sentry = (function (exports) {
4017
4018
  result = finalScope.applyToEvent(prepared, hint);
4018
4019
  }
4019
4020
  return result.then(function (evt) {
4021
+ if (evt) {
4022
+ // TODO this is more of the hack trying to solve https://github.com/getsentry/sentry-javascript/issues/2809
4023
+ // it is only attached as extra data to the event if the event somehow skips being normalized
4024
+ evt.sdkProcessingMetadata = __assign(__assign({}, evt.sdkProcessingMetadata), { normalizeDepth: normalize(normalizeDepth) });
4025
+ }
4020
4026
  if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {
4021
4027
  return _this._normalizeEvent(evt, normalizeDepth);
4022
4028
  }
@@ -4368,22 +4374,27 @@ var Sentry = (function (exports) {
4368
4374
  var transactionSampling = (event.sdkProcessingMetadata || {}).transactionSampling;
4369
4375
  var _a = transactionSampling || {}, samplingMethod = _a.method, sampleRate = _a.rate;
4370
4376
  // TODO: Below is a temporary hack in order to debug a serialization error - see
4371
- // https://github.com/getsentry/sentry-javascript/issues/2809 and
4372
- // https://github.com/getsentry/sentry-javascript/pull/4425. TL;DR: even though we normalize all events (which should
4373
- // prevent this), something is causing `JSON.stringify` to throw a circular reference error.
4377
+ // https://github.com/getsentry/sentry-javascript/issues/2809,
4378
+ // https://github.com/getsentry/sentry-javascript/pull/4425, and
4379
+ // https://github.com/getsentry/sentry-javascript/pull/4574.
4380
+ //
4381
+ // TL; DR: even though we normalize all events (which should prevent this), something is causing `JSON.stringify` to
4382
+ // throw a circular reference error.
4374
4383
  //
4375
4384
  // When it's time to remove it:
4376
4385
  // 1. Delete everything between here and where the request object `req` is created, EXCEPT the line deleting
4377
4386
  // `sdkProcessingMetadata`
4378
4387
  // 2. Restore the original version of the request body, which is commented out
4379
- // 3. Search for `skippedNormalization` and pull out the companion hack in the browser playwright tests
4388
+ // 3. Search for either of the PR URLs above and pull out the companion hacks in the browser playwright tests and the
4389
+ // baseClient tests in this package
4380
4390
  enhanceEventWithSdkInfo(event, api.metadata.sdk);
4381
4391
  event.tags = event.tags || {};
4382
4392
  event.extra = event.extra || {};
4383
4393
  // In theory, all events should be marked as having gone through normalization and so
4384
- // we should never set this tag
4394
+ // we should never set this tag/extra data
4385
4395
  if (!(event.sdkProcessingMetadata && event.sdkProcessingMetadata.baseClientNormalized)) {
4386
4396
  event.tags.skippedNormalization = true;
4397
+ event.extra.normalizeDepth = event.sdkProcessingMetadata ? event.sdkProcessingMetadata.normalizeDepth : 'unset';
4387
4398
  }
4388
4399
  // prevent this data from being sent to sentry
4389
4400
  // TODO: This is NOT part of the hack - DO NOT DELETE
@@ -4465,7 +4476,7 @@ var Sentry = (function (exports) {
4465
4476
  hub.bindClient(client);
4466
4477
  }
4467
4478
 
4468
- var SDK_VERSION = '6.17.5';
4479
+ var SDK_VERSION = '6.17.8';
4469
4480
 
4470
4481
  var originalFunctionToString;
4471
4482
  /** Patch toString calls to return proper name for wrapped functions */
@@ -4688,206 +4699,90 @@ var Sentry = (function (exports) {
4688
4699
  InboundFilters: InboundFilters
4689
4700
  });
4690
4701
 
4691
- /**
4692
- * This was originally forked from https://github.com/occ/TraceKit, but has since been
4693
- * largely modified and is now maintained as part of Sentry JS SDK.
4694
- */
4695
4702
  // global reference to slice
4696
4703
  var UNKNOWN_FUNCTION = '?';
4697
- // Chromium based browsers: Chrome, Brave, new Opera, new Edge
4698
- var chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
4699
- // gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
4700
- // generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
4701
- // We need this specific case for now because we want no other regex to match.
4702
- var gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|capacitor).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
4703
- var winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
4704
- var geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
4705
- var chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/;
4706
- // Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
4707
- var reactMinifiedRegexp = /Minified React error #\d+;/i;
4708
- /** JSDoc */
4709
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
4710
- function computeStackTrace(ex) {
4711
- var stack = null;
4712
- var popSize = 0;
4713
- if (ex) {
4714
- if (typeof ex.framesToPop === 'number') {
4715
- popSize = ex.framesToPop;
4716
- }
4717
- else if (reactMinifiedRegexp.test(ex.message)) {
4718
- popSize = 1;
4719
- }
4720
- }
4721
- try {
4722
- // This must be tried first because Opera 10 *destroys*
4723
- // its stacktrace property if you try to access the stack
4724
- // property first!!
4725
- stack = computeStackTraceFromStacktraceProp(ex);
4726
- if (stack) {
4727
- return popFrames(stack, popSize);
4728
- }
4729
- }
4730
- catch (e) {
4731
- // no-empty
4732
- }
4733
- try {
4734
- stack = computeStackTraceFromStackProp(ex);
4735
- if (stack) {
4736
- return popFrames(stack, popSize);
4737
- }
4704
+ function createFrame(filename, func, lineno, colno) {
4705
+ var frame = {
4706
+ filename: filename,
4707
+ function: func,
4708
+ // All browser frames are considered in_app
4709
+ in_app: true,
4710
+ };
4711
+ if (lineno !== undefined) {
4712
+ frame.lineno = lineno;
4738
4713
  }
4739
- catch (e) {
4740
- // no-empty
4714
+ if (colno !== undefined) {
4715
+ frame.colno = colno;
4741
4716
  }
4742
- return {
4743
- message: extractMessage(ex),
4744
- name: ex && ex.name,
4745
- stack: [],
4746
- failed: true,
4747
- };
4717
+ return frame;
4748
4718
  }
4749
- /** JSDoc */
4750
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, complexity
4751
- function computeStackTraceFromStackProp(ex) {
4752
- var _a, _b;
4753
- if (!ex || !ex.stack) {
4754
- return null;
4755
- }
4756
- var stack = [];
4757
- var lines = ex.stack.split('\n');
4758
- var isEval;
4759
- var submatch;
4760
- var parts;
4761
- var element;
4762
- for (var i = 0; i < lines.length; ++i) {
4763
- if ((parts = chrome.exec(lines[i]))) {
4764
- var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
4765
- isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
4766
- if (isEval && (submatch = chromeEval.exec(parts[2]))) {
4719
+ // Chromium based browsers: Chrome, Brave, new Opera, new Edge
4720
+ var chromeRegex = /^\s*at (?:(.*?) ?\((?:address at )?)?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
4721
+ var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
4722
+ var chrome = function (line) {
4723
+ var parts = chromeRegex.exec(line);
4724
+ if (parts) {
4725
+ var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
4726
+ if (isEval) {
4727
+ var subMatch = chromeEvalRegex.exec(parts[2]);
4728
+ if (subMatch) {
4767
4729
  // throw out eval line/column and use top-most line/column number
4768
- parts[2] = submatch[1]; // url
4769
- parts[3] = submatch[2]; // line
4770
- parts[4] = submatch[3]; // column
4730
+ parts[2] = subMatch[1]; // url
4731
+ parts[3] = subMatch[2]; // line
4732
+ parts[4] = subMatch[3]; // column
4771
4733
  }
4772
- // Arpad: Working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `
4773
- // prefix here seems like the quickest solution for now.
4774
- var url = parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2];
4775
- // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
4776
- // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
4777
- var func = parts[1] || UNKNOWN_FUNCTION;
4778
- _a = __read(extractSafariExtensionDetails(func, url), 2), func = _a[0], url = _a[1];
4779
- element = {
4780
- url: url,
4781
- func: func,
4782
- args: isNative ? [parts[2]] : [],
4783
- line: parts[3] ? +parts[3] : null,
4784
- column: parts[4] ? +parts[4] : null,
4785
- };
4786
- }
4787
- else if ((parts = winjs.exec(lines[i]))) {
4788
- element = {
4789
- url: parts[2],
4790
- func: parts[1] || UNKNOWN_FUNCTION,
4791
- args: [],
4792
- line: +parts[3],
4793
- column: parts[4] ? +parts[4] : null,
4794
- };
4795
4734
  }
4796
- else if ((parts = gecko.exec(lines[i]))) {
4797
- isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
4798
- if (isEval && (submatch = geckoEval.exec(parts[3]))) {
4735
+ // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
4736
+ // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
4737
+ var _a = __read(extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]), 2), func = _a[0], filename = _a[1];
4738
+ return createFrame(filename, func, parts[3] ? +parts[3] : undefined, parts[4] ? +parts[4] : undefined);
4739
+ }
4740
+ return;
4741
+ };
4742
+ // gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
4743
+ // generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
4744
+ // We need this specific case for now because we want no other regex to match.
4745
+ var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|capacitor).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
4746
+ var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
4747
+ var gecko = function (line) {
4748
+ var _a;
4749
+ var parts = geckoREgex.exec(line);
4750
+ if (parts) {
4751
+ var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
4752
+ if (isEval) {
4753
+ var subMatch = geckoEvalRegex.exec(parts[3]);
4754
+ if (subMatch) {
4799
4755
  // throw out eval line/column and use top-most line number
4800
4756
  parts[1] = parts[1] || "eval";
4801
- parts[3] = submatch[1];
4802
- parts[4] = submatch[2];
4757
+ parts[3] = subMatch[1];
4758
+ parts[4] = subMatch[2];
4803
4759
  parts[5] = ''; // no column when eval
4804
4760
  }
4805
- else if (i === 0 && !parts[5] && ex.columnNumber !== void 0) {
4806
- // FireFox uses this awesome columnNumber property for its top frame
4807
- // Also note, Firefox's column number is 0-based and everything else expects 1-based,
4808
- // so adding 1
4809
- // NOTE: this hack doesn't work if top-most frame is eval
4810
- stack[0].column = ex.columnNumber + 1;
4811
- }
4812
- var url = parts[3];
4813
- var func = parts[1] || UNKNOWN_FUNCTION;
4814
- _b = __read(extractSafariExtensionDetails(func, url), 2), func = _b[0], url = _b[1];
4815
- element = {
4816
- url: url,
4817
- func: func,
4818
- args: parts[2] ? parts[2].split(',') : [],
4819
- line: parts[4] ? +parts[4] : null,
4820
- column: parts[5] ? +parts[5] : null,
4821
- };
4822
- }
4823
- else {
4824
- continue;
4825
4761
  }
4826
- if (!element.func && element.line) {
4827
- element.func = UNKNOWN_FUNCTION;
4828
- }
4829
- stack.push(element);
4830
- }
4831
- if (!stack.length) {
4832
- return null;
4833
- }
4834
- return {
4835
- message: extractMessage(ex),
4836
- name: ex.name,
4837
- stack: stack,
4838
- };
4839
- }
4840
- /** JSDoc */
4841
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4842
- function computeStackTraceFromStacktraceProp(ex) {
4843
- if (!ex || !ex.stacktrace) {
4844
- return null;
4762
+ var filename = parts[3];
4763
+ var func = parts[1] || UNKNOWN_FUNCTION;
4764
+ _a = __read(extractSafariExtensionDetails(func, filename), 2), func = _a[0], filename = _a[1];
4765
+ return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);
4845
4766
  }
4846
- // Access and store the stacktrace property before doing ANYTHING
4847
- // else to it because Opera is not very good at providing it
4848
- // reliably in other circumstances.
4849
- var stacktrace = ex.stacktrace;
4850
- var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
4851
- var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\((.*)\))? in (.*):\s*$/i;
4852
- var lines = stacktrace.split('\n');
4853
- var stack = [];
4854
- var parts;
4855
- for (var line = 0; line < lines.length; line += 2) {
4856
- var element = null;
4857
- if ((parts = opera10Regex.exec(lines[line]))) {
4858
- element = {
4859
- url: parts[2],
4860
- func: parts[3],
4861
- args: [],
4862
- line: +parts[1],
4863
- column: null,
4864
- };
4865
- }
4866
- else if ((parts = opera11Regex.exec(lines[line]))) {
4867
- element = {
4868
- url: parts[6],
4869
- func: parts[3] || parts[4],
4870
- args: parts[5] ? parts[5].split(',') : [],
4871
- line: +parts[1],
4872
- column: +parts[2],
4873
- };
4874
- }
4875
- if (element) {
4876
- if (!element.func && element.line) {
4877
- element.func = UNKNOWN_FUNCTION;
4878
- }
4879
- stack.push(element);
4880
- }
4881
- }
4882
- if (!stack.length) {
4883
- return null;
4884
- }
4885
- return {
4886
- message: extractMessage(ex),
4887
- name: ex.name,
4888
- stack: stack,
4889
- };
4890
- }
4767
+ return;
4768
+ };
4769
+ var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
4770
+ var winjs = function (line) {
4771
+ var parts = winjsRegex.exec(line);
4772
+ return parts
4773
+ ? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)
4774
+ : undefined;
4775
+ };
4776
+ var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
4777
+ var opera10 = function (line) {
4778
+ var parts = opera10Regex.exec(line);
4779
+ return parts ? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : undefined;
4780
+ };
4781
+ var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
4782
+ var opera11 = function (line) {
4783
+ var parts = opera11Regex.exec(line);
4784
+ return parts ? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
4785
+ };
4891
4786
  /**
4892
4787
  * Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.
4893
4788
  * What it means, is that instead of format like:
@@ -4905,56 +4800,31 @@ var Sentry = (function (exports) {
4905
4800
  *
4906
4801
  * Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.
4907
4802
  * This function is extracted so that we can use it in both places without duplicating the logic.
4908
- * Unfortunatelly "just" changing RegExp is too complicated now and making it pass all tests
4803
+ * Unfortunately "just" changing RegExp is too complicated now and making it pass all tests
4909
4804
  * and fix this case seems like an impossible, or at least way too time-consuming task.
4910
4805
  */
4911
- var extractSafariExtensionDetails = function (func, url) {
4806
+ var extractSafariExtensionDetails = function (func, filename) {
4912
4807
  var isSafariExtension = func.indexOf('safari-extension') !== -1;
4913
4808
  var isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;
4914
4809
  return isSafariExtension || isSafariWebExtension
4915
4810
  ? [
4916
4811
  func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,
4917
- isSafariExtension ? "safari-extension:" + url : "safari-web-extension:" + url,
4812
+ isSafariExtension ? "safari-extension:" + filename : "safari-web-extension:" + filename,
4918
4813
  ]
4919
- : [func, url];
4920
- };
4921
- /** Remove N number of frames from the stack */
4922
- function popFrames(stacktrace, popSize) {
4923
- try {
4924
- return __assign(__assign({}, stacktrace), { stack: stacktrace.stack.slice(popSize) });
4925
- }
4926
- catch (e) {
4927
- return stacktrace;
4928
- }
4929
- }
4930
- /**
4931
- * There are cases where stacktrace.message is an Event object
4932
- * https://github.com/getsentry/sentry-javascript/issues/1949
4933
- * In this specific case we try to extract stacktrace.message.error.message
4934
- */
4935
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4936
- function extractMessage(ex) {
4937
- var message = ex && ex.message;
4938
- if (!message) {
4939
- return 'No error message';
4940
- }
4941
- if (message.error && typeof message.error.message === 'string') {
4942
- return message.error.message;
4943
- }
4944
- return message;
4945
- }
4814
+ : [func, filename];
4815
+ };
4946
4816
 
4947
- var STACKTRACE_LIMIT = 50;
4948
4817
  /**
4949
4818
  * This function creates an exception from an TraceKitStackTrace
4950
4819
  * @param stacktrace TraceKitStackTrace that will be converted to an exception
4951
4820
  * @hidden
4952
4821
  */
4953
- function exceptionFromStacktrace(stacktrace) {
4954
- var frames = prepareFramesForEvent(stacktrace.stack);
4822
+ function exceptionFromError(ex) {
4823
+ // Get the frames first since Opera can lose the stack if we touch anything else first
4824
+ var frames = parseStackFrames(ex);
4955
4825
  var exception = {
4956
- type: stacktrace.name,
4957
- value: stacktrace.message,
4826
+ type: ex && ex.name,
4827
+ value: extractMessage(ex),
4958
4828
  };
4959
4829
  if (frames && frames.length) {
4960
4830
  exception.stacktrace = { frames: frames };
@@ -4982,10 +4852,8 @@ var Sentry = (function (exports) {
4982
4852
  },
4983
4853
  };
4984
4854
  if (syntheticException) {
4985
- var stacktrace = computeStackTrace(syntheticException);
4986
- var frames_1 = prepareFramesForEvent(stacktrace.stack);
4987
4855
  event.stacktrace = {
4988
- frames: frames_1,
4856
+ frames: parseStackFrames(syntheticException),
4989
4857
  };
4990
4858
  }
4991
4859
  return event;
@@ -4993,43 +4861,57 @@ var Sentry = (function (exports) {
4993
4861
  /**
4994
4862
  * @hidden
4995
4863
  */
4996
- function eventFromStacktrace(stacktrace) {
4997
- var exception = exceptionFromStacktrace(stacktrace);
4864
+ function eventFromError(ex) {
4998
4865
  return {
4999
4866
  exception: {
5000
- values: [exception],
4867
+ values: [exceptionFromError(ex)],
5001
4868
  },
5002
4869
  };
5003
4870
  }
4871
+ /** Parses stack frames from an error */
4872
+ function parseStackFrames(ex) {
4873
+ // Access and store the stacktrace property before doing ANYTHING
4874
+ // else to it because Opera is not very good at providing it
4875
+ // reliably in other circumstances.
4876
+ var stacktrace = ex.stacktrace || ex.stack || '';
4877
+ var popSize = getPopSize(ex);
4878
+ try {
4879
+ // The order of the parsers in important
4880
+ return createStackParser(opera10, opera11, chrome, winjs, gecko)(stacktrace, popSize);
4881
+ }
4882
+ catch (e) {
4883
+ // no-empty
4884
+ }
4885
+ return [];
4886
+ }
4887
+ // Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
4888
+ var reactMinifiedRegexp = /Minified React error #\d+;/i;
4889
+ function getPopSize(ex) {
4890
+ if (ex) {
4891
+ if (typeof ex.framesToPop === 'number') {
4892
+ return ex.framesToPop;
4893
+ }
4894
+ if (reactMinifiedRegexp.test(ex.message)) {
4895
+ return 1;
4896
+ }
4897
+ }
4898
+ return 0;
4899
+ }
5004
4900
  /**
5005
- * @hidden
4901
+ * There are cases where stacktrace.message is an Event object
4902
+ * https://github.com/getsentry/sentry-javascript/issues/1949
4903
+ * In this specific case we try to extract stacktrace.message.error.message
5006
4904
  */
5007
- function prepareFramesForEvent(stack) {
5008
- if (!stack || !stack.length) {
5009
- return [];
5010
- }
5011
- var localStack = stack;
5012
- var firstFrameFunction = localStack[0].func || '';
5013
- var lastFrameFunction = localStack[localStack.length - 1].func || '';
5014
- // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
5015
- if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
5016
- localStack = localStack.slice(1);
4905
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4906
+ function extractMessage(ex) {
4907
+ var message = ex && ex.message;
4908
+ if (!message) {
4909
+ return 'No error message';
5017
4910
  }
5018
- // 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)
5019
- if (lastFrameFunction.indexOf('sentryWrapped') !== -1) {
5020
- localStack = localStack.slice(0, -1);
4911
+ if (message.error && typeof message.error.message === 'string') {
4912
+ return message.error.message;
5021
4913
  }
5022
- // The frame where the crash happened, should be the last entry in the array
5023
- return localStack
5024
- .slice(0, STACKTRACE_LIMIT)
5025
- .map(function (frame) { return ({
5026
- colno: frame.column === null ? undefined : frame.column,
5027
- filename: frame.url || localStack[0].url,
5028
- function: frame.func || '?',
5029
- in_app: true,
5030
- lineno: frame.line === null ? undefined : frame.line,
5031
- }); })
5032
- .reverse();
4914
+ return message;
5033
4915
  }
5034
4916
 
5035
4917
  /**
@@ -5073,10 +4955,7 @@ var Sentry = (function (exports) {
5073
4955
  if (isErrorEvent(exception) && exception.error) {
5074
4956
  // If it is an ErrorEvent with `error` property, extract it to get actual Error
5075
4957
  var errorEvent = exception;
5076
- // eslint-disable-next-line no-param-reassign
5077
- exception = errorEvent.error;
5078
- event = eventFromStacktrace(computeStackTrace(exception));
5079
- return event;
4958
+ return eventFromError(errorEvent.error);
5080
4959
  }
5081
4960
  // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
5082
4961
  // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
@@ -5088,7 +4967,7 @@ var Sentry = (function (exports) {
5088
4967
  if (isDOMError(exception) || isDOMException(exception)) {
5089
4968
  var domException = exception;
5090
4969
  if ('stack' in exception) {
5091
- event = eventFromStacktrace(computeStackTrace(exception));
4970
+ event = eventFromError(exception);
5092
4971
  }
5093
4972
  else {
5094
4973
  var name_1 = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');
@@ -5103,8 +4982,7 @@ var Sentry = (function (exports) {
5103
4982
  }
5104
4983
  if (isError(exception)) {
5105
4984
  // we have a real Error object, do nothing
5106
- event = eventFromStacktrace(computeStackTrace(exception));
5107
- return event;
4985
+ return eventFromError(exception);
5108
4986
  }
5109
4987
  if (isPlainObject(exception) || isEvent(exception)) {
5110
4988
  // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
@@ -5142,10 +5020,8 @@ var Sentry = (function (exports) {
5142
5020
  message: input,
5143
5021
  };
5144
5022
  if (options.attachStacktrace && syntheticException) {
5145
- var stacktrace = computeStackTrace(syntheticException);
5146
- var frames_1 = prepareFramesForEvent(stacktrace.stack);
5147
5023
  event.stacktrace = {
5148
- frames: frames_1,
5024
+ frames: parseStackFrames(syntheticException),
5149
5025
  };
5150
5026
  }
5151
5027
  return event;
@@ -6471,8 +6347,7 @@ var Sentry = (function (exports) {
6471
6347
  if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
6472
6348
  return stack;
6473
6349
  }
6474
- var stacktrace = computeStackTrace(error[key]);
6475
- var exception = exceptionFromStacktrace(stacktrace);
6350
+ var exception = exceptionFromError(error[key]);
6476
6351
  return _walkErrorTree(limit, error[key], key, __spread([exception], stack));
6477
6352
  }
6478
6353