@sentry/browser 6.15.0 → 6.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/build/bundle.es6.js +1265 -1435
  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 +1304 -1490
  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 +2 -2
  10. package/dist/eventbuilder.d.ts.map +1 -1
  11. package/dist/eventbuilder.js +7 -7
  12. package/dist/eventbuilder.js.map +1 -1
  13. package/dist/exports.d.ts +1 -1
  14. package/dist/exports.d.ts.map +1 -1
  15. package/dist/exports.js +0 -1
  16. package/dist/exports.js.map +1 -1
  17. package/dist/helpers.d.ts.map +1 -1
  18. package/dist/helpers.js +26 -37
  19. package/dist/helpers.js.map +1 -1
  20. package/dist/integrations/breadcrumbs.d.ts +0 -20
  21. package/dist/integrations/breadcrumbs.d.ts.map +1 -1
  22. package/dist/integrations/breadcrumbs.js +132 -173
  23. package/dist/integrations/breadcrumbs.js.map +1 -1
  24. package/dist/integrations/dedupe.d.ts +0 -14
  25. package/dist/integrations/dedupe.d.ts.map +1 -1
  26. package/dist/integrations/dedupe.js +126 -126
  27. package/dist/integrations/dedupe.js.map +1 -1
  28. package/dist/integrations/globalhandlers.d.ts +7 -25
  29. package/dist/integrations/globalhandlers.d.ts.map +1 -1
  30. package/dist/integrations/globalhandlers.js +176 -168
  31. package/dist/integrations/globalhandlers.js.map +1 -1
  32. package/dist/integrations/linkederrors.d.ts +15 -13
  33. package/dist/integrations/linkederrors.d.ts.map +1 -1
  34. package/dist/integrations/linkederrors.js +26 -28
  35. package/dist/integrations/linkederrors.js.map +1 -1
  36. package/dist/integrations/trycatch.d.ts +0 -8
  37. package/dist/integrations/trycatch.d.ts.map +1 -1
  38. package/dist/integrations/trycatch.js +154 -153
  39. package/dist/integrations/trycatch.js.map +1 -1
  40. package/dist/integrations/useragent.js +2 -3
  41. package/dist/integrations/useragent.js.map +1 -1
  42. package/dist/sdk.d.ts.map +1 -1
  43. package/dist/sdk.js +23 -19
  44. package/dist/sdk.js.map +1 -1
  45. package/dist/transports/base.d.ts +9 -4
  46. package/dist/transports/base.d.ts.map +1 -1
  47. package/dist/transports/base.js +23 -19
  48. package/dist/transports/base.js.map +1 -1
  49. package/dist/transports/fetch.d.ts +2 -10
  50. package/dist/transports/fetch.d.ts.map +1 -1
  51. package/dist/transports/fetch.js +6 -20
  52. package/dist/transports/fetch.js.map +1 -1
  53. package/dist/transports/utils.d.ts.map +1 -1
  54. package/dist/transports/utils.js +7 -5
  55. package/dist/transports/utils.js.map +1 -1
  56. package/dist/transports/xhr.d.ts +2 -10
  57. package/dist/transports/xhr.d.ts.map +1 -1
  58. package/dist/transports/xhr.js +3 -17
  59. package/dist/transports/xhr.js.map +1 -1
  60. package/esm/eventbuilder.d.ts +2 -2
  61. package/esm/eventbuilder.d.ts.map +1 -1
  62. package/esm/eventbuilder.js +8 -8
  63. package/esm/eventbuilder.js.map +1 -1
  64. package/esm/exports.d.ts +1 -1
  65. package/esm/exports.d.ts.map +1 -1
  66. package/esm/exports.js +1 -1
  67. package/esm/exports.js.map +1 -1
  68. package/esm/helpers.d.ts.map +1 -1
  69. package/esm/helpers.js +28 -39
  70. package/esm/helpers.js.map +1 -1
  71. package/esm/integrations/breadcrumbs.d.ts +0 -20
  72. package/esm/integrations/breadcrumbs.d.ts.map +1 -1
  73. package/esm/integrations/breadcrumbs.js +134 -175
  74. package/esm/integrations/breadcrumbs.js.map +1 -1
  75. package/esm/integrations/dedupe.d.ts +0 -14
  76. package/esm/integrations/dedupe.d.ts.map +1 -1
  77. package/esm/integrations/dedupe.js +126 -126
  78. package/esm/integrations/dedupe.js.map +1 -1
  79. package/esm/integrations/globalhandlers.d.ts +7 -25
  80. package/esm/integrations/globalhandlers.d.ts.map +1 -1
  81. package/esm/integrations/globalhandlers.js +178 -170
  82. package/esm/integrations/globalhandlers.js.map +1 -1
  83. package/esm/integrations/linkederrors.d.ts +15 -13
  84. package/esm/integrations/linkederrors.d.ts.map +1 -1
  85. package/esm/integrations/linkederrors.js +24 -28
  86. package/esm/integrations/linkederrors.js.map +1 -1
  87. package/esm/integrations/trycatch.d.ts +0 -8
  88. package/esm/integrations/trycatch.d.ts.map +1 -1
  89. package/esm/integrations/trycatch.js +155 -154
  90. package/esm/integrations/trycatch.js.map +1 -1
  91. package/esm/integrations/useragent.js +2 -3
  92. package/esm/integrations/useragent.js.map +1 -1
  93. package/esm/sdk.d.ts.map +1 -1
  94. package/esm/sdk.js +24 -20
  95. package/esm/sdk.js.map +1 -1
  96. package/esm/transports/base.d.ts +9 -4
  97. package/esm/transports/base.d.ts.map +1 -1
  98. package/esm/transports/base.js +25 -21
  99. package/esm/transports/base.js.map +1 -1
  100. package/esm/transports/fetch.d.ts +2 -10
  101. package/esm/transports/fetch.d.ts.map +1 -1
  102. package/esm/transports/fetch.js +6 -20
  103. package/esm/transports/fetch.js.map +1 -1
  104. package/esm/transports/utils.d.ts.map +1 -1
  105. package/esm/transports/utils.js +8 -6
  106. package/esm/transports/utils.js.map +1 -1
  107. package/esm/transports/xhr.d.ts +2 -10
  108. package/esm/transports/xhr.d.ts.map +1 -1
  109. package/esm/transports/xhr.js +3 -17
  110. package/esm/transports/xhr.js.map +1 -1
  111. package/package.json +15 -17
@@ -1,43 +1,8 @@
1
- /*! @sentry/browser 6.15.0 (aa30ab6) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.17.0 (ad2f4ad) | https://github.com/getsentry/sentry-javascript */
2
2
  var Sentry = (function (exports) {
3
- /** Console logging verbosity for the SDK. */
4
- var LogLevel;
5
- (function (LogLevel) {
6
- /** No logs will be generated. */
7
- LogLevel[LogLevel["None"] = 0] = "None";
8
- /** Only SDK internal errors will be logged. */
9
- LogLevel[LogLevel["Error"] = 1] = "Error";
10
- /** Information useful for debugging the SDK will be logged. */
11
- LogLevel[LogLevel["Debug"] = 2] = "Debug";
12
- /** All SDK actions will be logged. */
13
- LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
14
- })(LogLevel || (LogLevel = {}));
15
-
16
3
  /**
17
- * Session Status
4
+ * TODO(v7): Remove this enum and replace with SeverityLevel
18
5
  */
19
- var SessionStatus;
20
- (function (SessionStatus) {
21
- /** JSDoc */
22
- SessionStatus["Ok"] = "ok";
23
- /** JSDoc */
24
- SessionStatus["Exited"] = "exited";
25
- /** JSDoc */
26
- SessionStatus["Crashed"] = "crashed";
27
- /** JSDoc */
28
- SessionStatus["Abnormal"] = "abnormal";
29
- })(SessionStatus || (SessionStatus = {}));
30
- var RequestSessionStatus;
31
- (function (RequestSessionStatus) {
32
- /** JSDoc */
33
- RequestSessionStatus["Ok"] = "ok";
34
- /** JSDoc */
35
- RequestSessionStatus["Errored"] = "errored";
36
- /** JSDoc */
37
- RequestSessionStatus["Crashed"] = "crashed";
38
- })(RequestSessionStatus || (RequestSessionStatus = {}));
39
-
40
- /** JSDoc */
41
6
  (function (Severity) {
42
7
  /** JSDoc */
43
8
  Severity["Fatal"] = "fatal";
@@ -54,95 +19,7 @@ var Sentry = (function (exports) {
54
19
  /** JSDoc */
55
20
  Severity["Critical"] = "critical";
56
21
  })(exports.Severity || (exports.Severity = {}));
57
- // eslint-disable-next-line @typescript-eslint/no-namespace, import/export
58
- (function (Severity) {
59
- /**
60
- * Converts a string-based level into a {@link Severity}.
61
- *
62
- * @param level string representation of Severity
63
- * @returns Severity
64
- */
65
- function fromString(level) {
66
- switch (level) {
67
- case 'debug':
68
- return Severity.Debug;
69
- case 'info':
70
- return Severity.Info;
71
- case 'warn':
72
- case 'warning':
73
- return Severity.Warning;
74
- case 'error':
75
- return Severity.Error;
76
- case 'fatal':
77
- return Severity.Fatal;
78
- case 'critical':
79
- return Severity.Critical;
80
- case 'log':
81
- default:
82
- return Severity.Log;
83
- }
84
- }
85
- Severity.fromString = fromString;
86
- })(exports.Severity || (exports.Severity = {}));
87
-
88
- /** The status of an event. */
89
- (function (Status) {
90
- /** The status could not be determined. */
91
- Status["Unknown"] = "unknown";
92
- /** The event was skipped due to configuration or callbacks. */
93
- Status["Skipped"] = "skipped";
94
- /** The event was sent to Sentry successfully. */
95
- Status["Success"] = "success";
96
- /** The client is currently rate limited and will try again later. */
97
- Status["RateLimit"] = "rate_limit";
98
- /** The event could not be processed. */
99
- Status["Invalid"] = "invalid";
100
- /** A server-side error occurred during submission. */
101
- Status["Failed"] = "failed";
102
- })(exports.Status || (exports.Status = {}));
103
- // eslint-disable-next-line @typescript-eslint/no-namespace, import/export
104
- (function (Status) {
105
- /**
106
- * Converts a HTTP status code into a {@link Status}.
107
- *
108
- * @param code The HTTP response status code.
109
- * @returns The send status or {@link Status.Unknown}.
110
- */
111
- function fromHttpCode(code) {
112
- if (code >= 200 && code < 300) {
113
- return Status.Success;
114
- }
115
- if (code === 429) {
116
- return Status.RateLimit;
117
- }
118
- if (code >= 400 && code < 500) {
119
- return Status.Invalid;
120
- }
121
- if (code >= 500) {
122
- return Status.Failed;
123
- }
124
- return Status.Unknown;
125
- }
126
- Status.fromHttpCode = fromHttpCode;
127
- })(exports.Status || (exports.Status = {}));
128
-
129
- var TransactionSamplingMethod;
130
- (function (TransactionSamplingMethod) {
131
- TransactionSamplingMethod["Explicit"] = "explicitly_set";
132
- TransactionSamplingMethod["Sampler"] = "client_sampler";
133
- TransactionSamplingMethod["Rate"] = "client_rate";
134
- TransactionSamplingMethod["Inheritance"] = "inheritance";
135
- })(TransactionSamplingMethod || (TransactionSamplingMethod = {}));
136
-
137
- var Outcome;
138
- (function (Outcome) {
139
- Outcome["BeforeSend"] = "before_send";
140
- Outcome["EventProcessor"] = "event_processor";
141
- Outcome["NetworkError"] = "network_error";
142
- Outcome["QueueOverflow"] = "queue_overflow";
143
- Outcome["RateLimitBackoff"] = "ratelimit_backoff";
144
- Outcome["SampleRate"] = "sample_rate";
145
- })(Outcome || (Outcome = {}));
22
+ const SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'];
146
23
 
147
24
  /**
148
25
  * Consumes the promise and logs the error when it rejects.
@@ -157,6 +34,33 @@ var Sentry = (function (exports) {
157
34
  });
158
35
  }
159
36
 
37
+ /**
38
+ * This module mostly exists for optimizations in the build process
39
+ * through rollup and terser. We define some global constants which
40
+ * are normally undefined. However terser overrides these with global
41
+ * definitions which can be evaluated by the static analyzer when
42
+ * creating a bundle.
43
+ *
44
+ * In turn the `isDebugBuild` and `isBrowserBundle` functions are pure
45
+ * and can help us remove unused code from the bundles.
46
+ */
47
+ /**
48
+ * Figures out if we're building with debug functionality.
49
+ *
50
+ * @returns true if this is a debug build
51
+ */
52
+ function isDebugBuild() {
53
+ return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !__SENTRY_BROWSER_BUNDLE__;
54
+ }
55
+ /**
56
+ * Figures out if we're building a browser bundle.
57
+ *
58
+ * @returns true if this is a browser bundle build.
59
+ */
60
+ function isBrowserBundle() {
61
+ return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
62
+ }
63
+
160
64
  /**
161
65
  * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
162
66
  * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
@@ -167,7 +71,10 @@ var Sentry = (function (exports) {
167
71
  * @returns Answer to given question
168
72
  */
169
73
  function isNodeEnv() {
170
- return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
74
+ // explicitly check for browser bundles as those can be optimized statically
75
+ // by terser/rollup.
76
+ return (!isBrowserBundle() &&
77
+ Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]');
171
78
  }
172
79
  /**
173
80
  * Requires a module which is protected against bundler minification.
@@ -202,6 +109,8 @@ var Sentry = (function (exports) {
202
109
 
203
110
  /* eslint-disable @typescript-eslint/no-explicit-any */
204
111
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
112
+ // eslint-disable-next-line @typescript-eslint/unbound-method
113
+ const objectToString = Object.prototype.toString;
205
114
  /**
206
115
  * Checks whether given value's type is one of a few Error or Error-like
207
116
  * {@link isError}.
@@ -210,17 +119,18 @@ var Sentry = (function (exports) {
210
119
  * @returns A boolean representing the result.
211
120
  */
212
121
  function isError(wat) {
213
- switch (Object.prototype.toString.call(wat)) {
122
+ switch (objectToString.call(wat)) {
214
123
  case '[object Error]':
215
- return true;
216
124
  case '[object Exception]':
217
- return true;
218
125
  case '[object DOMException]':
219
126
  return true;
220
127
  default:
221
128
  return isInstanceOf(wat, Error);
222
129
  }
223
130
  }
131
+ function isBuiltin(wat, ty) {
132
+ return objectToString.call(wat) === `[object ${ty}]`;
133
+ }
224
134
  /**
225
135
  * Checks whether given value's type is ErrorEvent
226
136
  * {@link isErrorEvent}.
@@ -229,7 +139,7 @@ var Sentry = (function (exports) {
229
139
  * @returns A boolean representing the result.
230
140
  */
231
141
  function isErrorEvent(wat) {
232
- return Object.prototype.toString.call(wat) === '[object ErrorEvent]';
142
+ return isBuiltin(wat, 'ErrorEvent');
233
143
  }
234
144
  /**
235
145
  * Checks whether given value's type is DOMError
@@ -239,7 +149,7 @@ var Sentry = (function (exports) {
239
149
  * @returns A boolean representing the result.
240
150
  */
241
151
  function isDOMError(wat) {
242
- return Object.prototype.toString.call(wat) === '[object DOMError]';
152
+ return isBuiltin(wat, 'DOMError');
243
153
  }
244
154
  /**
245
155
  * Checks whether given value's type is DOMException
@@ -249,7 +159,7 @@ var Sentry = (function (exports) {
249
159
  * @returns A boolean representing the result.
250
160
  */
251
161
  function isDOMException(wat) {
252
- return Object.prototype.toString.call(wat) === '[object DOMException]';
162
+ return isBuiltin(wat, 'DOMException');
253
163
  }
254
164
  /**
255
165
  * Checks whether given value's type is a string
@@ -259,10 +169,10 @@ var Sentry = (function (exports) {
259
169
  * @returns A boolean representing the result.
260
170
  */
261
171
  function isString(wat) {
262
- return Object.prototype.toString.call(wat) === '[object String]';
172
+ return isBuiltin(wat, 'String');
263
173
  }
264
174
  /**
265
- * Checks whether given value's is a primitive (undefined, null, number, boolean, string, bigint, symbol)
175
+ * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)
266
176
  * {@link isPrimitive}.
267
177
  *
268
178
  * @param wat A value to be checked.
@@ -279,7 +189,7 @@ var Sentry = (function (exports) {
279
189
  * @returns A boolean representing the result.
280
190
  */
281
191
  function isPlainObject(wat) {
282
- return Object.prototype.toString.call(wat) === '[object Object]';
192
+ return isBuiltin(wat, 'Object');
283
193
  }
284
194
  /**
285
195
  * Checks whether given value's type is an Event instance
@@ -309,7 +219,7 @@ var Sentry = (function (exports) {
309
219
  * @returns A boolean representing the result.
310
220
  */
311
221
  function isRegExp(wat) {
312
- return Object.prototype.toString.call(wat) === '[object RegExp]';
222
+ return isBuiltin(wat, 'RegExp');
313
223
  }
314
224
  /**
315
225
  * Checks whether given value has a then function.
@@ -393,7 +303,6 @@ var Sentry = (function (exports) {
393
303
  * @returns generated DOM path
394
304
  */
395
305
  function _htmlElementAsString(el, keyAttrs) {
396
- var _a, _b;
397
306
  const elem = el;
398
307
  const out = [];
399
308
  let className;
@@ -406,9 +315,10 @@ var Sentry = (function (exports) {
406
315
  }
407
316
  out.push(elem.tagName.toLowerCase());
408
317
  // Pairs of attribute keys defined in `serializeAttribute` and their values on element.
409
- const keyAttrPairs = ((_a = keyAttrs) === null || _a === void 0 ? void 0 : _a.length) ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
318
+ const keyAttrPairs = keyAttrs && keyAttrs.length
319
+ ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
410
320
  : null;
411
- if ((_b = keyAttrPairs) === null || _b === void 0 ? void 0 : _b.length) {
321
+ if (keyAttrPairs && keyAttrPairs.length) {
412
322
  keyAttrPairs.forEach(keyAttrPair => {
413
323
  out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
414
324
  });
@@ -485,88 +395,87 @@ var Sentry = (function (exports) {
485
395
 
486
396
  /** Regular expression used to parse a Dsn. */
487
397
  const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/;
488
- /** Error message */
489
- const ERROR_MESSAGE = 'Invalid Dsn';
490
- /** The Sentry Dsn, identifying a Sentry instance and project. */
491
- class Dsn {
492
- /** Creates a new Dsn component */
493
- constructor(from) {
494
- if (typeof from === 'string') {
495
- this._fromString(from);
496
- }
497
- else {
498
- this._fromComponents(from);
499
- }
500
- this._validate();
398
+ function isValidProtocol(protocol) {
399
+ return protocol === 'http' || protocol === 'https';
400
+ }
401
+ /**
402
+ * Renders the string representation of this Dsn.
403
+ *
404
+ * By default, this will render the public representation without the password
405
+ * component. To get the deprecated private representation, set `withPassword`
406
+ * to true.
407
+ *
408
+ * @param withPassword When set to true, the password will be included.
409
+ */
410
+ function dsnToString(dsn, withPassword = false) {
411
+ const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
412
+ return (`${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
413
+ `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`);
414
+ }
415
+ function dsnFromString(str) {
416
+ const match = DSN_REGEX.exec(str);
417
+ if (!match) {
418
+ throw new SentryError(`Invalid Sentry Dsn: ${str}`);
501
419
  }
502
- /**
503
- * Renders the string representation of this Dsn.
504
- *
505
- * By default, this will render the public representation without the password
506
- * component. To get the deprecated private representation, set `withPassword`
507
- * to true.
508
- *
509
- * @param withPassword When set to true, the password will be included.
510
- */
511
- toString(withPassword = false) {
512
- const { host, path, pass, port, projectId, protocol, publicKey } = this;
513
- return (`${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
514
- `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`);
515
- }
516
- /** Parses a string into this Dsn. */
517
- _fromString(str) {
518
- const match = DSN_REGEX.exec(str);
519
- if (!match) {
520
- throw new SentryError(ERROR_MESSAGE);
521
- }
522
- const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
523
- let path = '';
524
- let projectId = lastPath;
525
- const split = projectId.split('/');
526
- if (split.length > 1) {
527
- path = split.slice(0, -1).join('/');
528
- projectId = split.pop();
529
- }
530
- if (projectId) {
531
- const projectMatch = projectId.match(/^\d+/);
532
- if (projectMatch) {
533
- projectId = projectMatch[0];
534
- }
535
- }
536
- this._fromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
537
- }
538
- /** Maps Dsn components into this instance. */
539
- _fromComponents(components) {
540
- // TODO this is for backwards compatibility, and can be removed in a future version
541
- if ('user' in components && !('publicKey' in components)) {
542
- components.publicKey = components.user;
543
- }
544
- this.user = components.publicKey || '';
545
- this.protocol = components.protocol;
546
- this.publicKey = components.publicKey || '';
547
- this.pass = components.pass || '';
548
- this.host = components.host;
549
- this.port = components.port || '';
550
- this.path = components.path || '';
551
- this.projectId = components.projectId;
552
- }
553
- /** Validates this Dsn and throws on error. */
554
- _validate() {
555
- ['protocol', 'publicKey', 'host', 'projectId'].forEach(component => {
556
- if (!this[component]) {
557
- throw new SentryError(`${ERROR_MESSAGE}: ${component} missing`);
558
- }
559
- });
560
- if (!this.projectId.match(/^\d+$/)) {
561
- throw new SentryError(`${ERROR_MESSAGE}: Invalid projectId ${this.projectId}`);
562
- }
563
- if (this.protocol !== 'http' && this.protocol !== 'https') {
564
- throw new SentryError(`${ERROR_MESSAGE}: Invalid protocol ${this.protocol}`);
420
+ const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
421
+ let path = '';
422
+ let projectId = lastPath;
423
+ const split = projectId.split('/');
424
+ if (split.length > 1) {
425
+ path = split.slice(0, -1).join('/');
426
+ projectId = split.pop();
427
+ }
428
+ if (projectId) {
429
+ const projectMatch = projectId.match(/^\d+/);
430
+ if (projectMatch) {
431
+ projectId = projectMatch[0];
565
432
  }
566
- if (this.port && isNaN(parseInt(this.port, 10))) {
567
- throw new SentryError(`${ERROR_MESSAGE}: Invalid port ${this.port}`);
433
+ }
434
+ return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
435
+ }
436
+ function dsnFromComponents(components) {
437
+ // TODO this is for backwards compatibility, and can be removed in a future version
438
+ if ('user' in components && !('publicKey' in components)) {
439
+ components.publicKey = components.user;
440
+ }
441
+ return {
442
+ user: components.publicKey || '',
443
+ protocol: components.protocol,
444
+ publicKey: components.publicKey || '',
445
+ pass: components.pass || '',
446
+ host: components.host,
447
+ port: components.port || '',
448
+ path: components.path || '',
449
+ projectId: components.projectId,
450
+ };
451
+ }
452
+ function validateDsn(dsn) {
453
+ if (!isDebugBuild()) {
454
+ return;
455
+ }
456
+ const { port, projectId, protocol } = dsn;
457
+ const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];
458
+ requiredComponents.forEach(component => {
459
+ if (!dsn[component]) {
460
+ throw new SentryError(`Invalid Sentry Dsn: ${component} missing`);
568
461
  }
462
+ });
463
+ if (!projectId.match(/^\d+$/)) {
464
+ throw new SentryError(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);
465
+ }
466
+ if (!isValidProtocol(protocol)) {
467
+ throw new SentryError(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);
468
+ }
469
+ if (port && isNaN(parseInt(port, 10))) {
470
+ throw new SentryError(`Invalid Sentry Dsn: Invalid port ${port}`);
569
471
  }
472
+ return true;
473
+ }
474
+ /** The Sentry Dsn, identifying a Sentry instance and project. */
475
+ function makeDsn(from) {
476
+ const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
477
+ validateDsn(components);
478
+ return components;
570
479
  }
571
480
 
572
481
  // TODO: Implement different loggers for different environments
@@ -653,54 +562,44 @@ var Sentry = (function (exports) {
653
562
 
654
563
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
655
564
  /* eslint-disable @typescript-eslint/no-explicit-any */
656
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
657
565
  /**
658
- * Memo class used for decycle json objects. Uses WeakSet if available otherwise array.
566
+ * Helper to decycle json objects
659
567
  */
660
- class Memo {
661
- constructor() {
662
- this._hasWeakSet = typeof WeakSet === 'function';
663
- this._inner = this._hasWeakSet ? new WeakSet() : [];
664
- }
665
- /**
666
- * Sets obj to remember.
667
- * @param obj Object to remember
668
- */
669
- memoize(obj) {
670
- if (this._hasWeakSet) {
671
- if (this._inner.has(obj)) {
568
+ function memoBuilder() {
569
+ const hasWeakSet = typeof WeakSet === 'function';
570
+ const inner = hasWeakSet ? new WeakSet() : [];
571
+ function memoize(obj) {
572
+ if (hasWeakSet) {
573
+ if (inner.has(obj)) {
672
574
  return true;
673
575
  }
674
- this._inner.add(obj);
576
+ inner.add(obj);
675
577
  return false;
676
578
  }
677
579
  // eslint-disable-next-line @typescript-eslint/prefer-for-of
678
- for (let i = 0; i < this._inner.length; i++) {
679
- const value = this._inner[i];
580
+ for (let i = 0; i < inner.length; i++) {
581
+ const value = inner[i];
680
582
  if (value === obj) {
681
583
  return true;
682
584
  }
683
585
  }
684
- this._inner.push(obj);
586
+ inner.push(obj);
685
587
  return false;
686
588
  }
687
- /**
688
- * Removes object from internal storage.
689
- * @param obj Object to forget
690
- */
691
- unmemoize(obj) {
692
- if (this._hasWeakSet) {
693
- this._inner.delete(obj);
589
+ function unmemoize(obj) {
590
+ if (hasWeakSet) {
591
+ inner.delete(obj);
694
592
  }
695
593
  else {
696
- for (let i = 0; i < this._inner.length; i++) {
697
- if (this._inner[i] === obj) {
698
- this._inner.splice(i, 1);
594
+ for (let i = 0; i < inner.length; i++) {
595
+ if (inner[i] === obj) {
596
+ inner.splice(i, 1);
699
597
  break;
700
598
  }
701
599
  }
702
600
  }
703
601
  }
602
+ return [memoize, unmemoize];
704
603
  }
705
604
 
706
605
  const defaultFunctionName = '<anonymous>';
@@ -797,13 +696,7 @@ var Sentry = (function (exports) {
797
696
  // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
798
697
  if (typeof wrapped === 'function') {
799
698
  try {
800
- wrapped.prototype = wrapped.prototype || {};
801
- Object.defineProperties(wrapped, {
802
- __sentry_original__: {
803
- enumerable: false,
804
- value: original,
805
- },
806
- });
699
+ markFunctionWrapped(wrapped, original);
807
700
  }
808
701
  catch (_Oo) {
809
702
  // This can throw if multiple fill happens on a global object like XMLHttpRequest
@@ -812,6 +705,41 @@ var Sentry = (function (exports) {
812
705
  }
813
706
  source[name] = wrapped;
814
707
  }
708
+ /**
709
+ * Defines a non enumerable property. This creates a non enumerable property on an object.
710
+ *
711
+ * @param func The function to set a property to
712
+ * @param name the name of the special sentry property
713
+ * @param value the property to define
714
+ */
715
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
716
+ function addNonEnumerableProperty(func, name, value) {
717
+ Object.defineProperty(func, name, {
718
+ value: value,
719
+ });
720
+ }
721
+ /**
722
+ * Remembers the original function on the wrapped function and
723
+ * patches up the prototype.
724
+ *
725
+ * @param wrapped the wrapper function
726
+ * @param original the original function that gets wrapped
727
+ */
728
+ function markFunctionWrapped(wrapped, original) {
729
+ const proto = original.prototype || {};
730
+ wrapped.prototype = original.prototype = proto;
731
+ addNonEnumerableProperty(wrapped, '__sentry_original__', original);
732
+ }
733
+ /**
734
+ * This extracts the original function if available. See
735
+ * `markFunctionWrapped` for more information.
736
+ *
737
+ * @param func the function to unwrap
738
+ * @returns the unwrapped version of the function if available.
739
+ */
740
+ function getOriginalFunction(func) {
741
+ return func.__sentry_original__;
742
+ }
815
743
  /**
816
744
  * Encodes given object into url-friendly format
817
745
  *
@@ -910,11 +838,11 @@ var Sentry = (function (exports) {
910
838
  * unchanged.
911
839
  */
912
840
  function serializeValue(value) {
913
- const type = Object.prototype.toString.call(value);
914
841
  // Node.js REPL notation
915
842
  if (typeof value === 'string') {
916
843
  return value;
917
844
  }
845
+ const type = Object.prototype.toString.call(value);
918
846
  if (type === '[object Object]') {
919
847
  return '[Object]';
920
848
  }
@@ -984,8 +912,8 @@ var Sentry = (function (exports) {
984
912
  * @param memo Optional Memo class handling decycling
985
913
  */
986
914
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
987
- function walk(key, value, depth = +Infinity, memo = new Memo()) {
988
- // If we reach the maximum depth, serialize whatever has left
915
+ function walk(key, value, depth = +Infinity, memo = memoBuilder()) {
916
+ // If we reach the maximum depth, serialize whatever is left
989
917
  if (depth === 0) {
990
918
  return serializeValue(value);
991
919
  }
@@ -995,17 +923,18 @@ var Sentry = (function (exports) {
995
923
  return value.toJSON();
996
924
  }
997
925
  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
998
- // If normalized value is a primitive, there are no branches left to walk, so we can just bail out, as theres no point in going down that branch any further
926
+ // If normalized value is a primitive, there are no branches left to walk, so bail out
999
927
  const normalized = normalizeValue(value, key);
1000
928
  if (isPrimitive(normalized)) {
1001
929
  return normalized;
1002
930
  }
1003
- // Create source that we will use for next itterations, either objectified error object (Error type with extracted keys:value pairs) or the input itself
931
+ // Create source that we will use for the next iteration. It will either be an objectified error object (`Error` type
932
+ // with extracted key:value pairs) or the input itself.
1004
933
  const source = getWalkSource(value);
1005
934
  // Create an accumulator that will act as a parent for all future itterations of that branch
1006
935
  const acc = Array.isArray(value) ? [] : {};
1007
936
  // If we already walked that branch, bail out, as it's circular reference
1008
- if (memo.memoize(value)) {
937
+ if (memo[0](value)) {
1009
938
  return '[Circular ~]';
1010
939
  }
1011
940
  // Walk all keys of the source
@@ -1018,7 +947,7 @@ var Sentry = (function (exports) {
1018
947
  acc[innerKey] = walk(innerKey, source[innerKey], depth - 1, memo);
1019
948
  }
1020
949
  // Once walked through all the branches, remove the parent from memo storage
1021
- memo.unmemoize(value);
950
+ memo[1](value);
1022
951
  // Return accumulated values
1023
952
  return acc;
1024
953
  }
@@ -1151,7 +1080,9 @@ var Sentry = (function (exports) {
1151
1080
  doc.head.removeChild(sandbox);
1152
1081
  }
1153
1082
  catch (err) {
1154
- logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
1083
+ if (isDebugBuild()) {
1084
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
1085
+ }
1155
1086
  }
1156
1087
  }
1157
1088
  return result;
@@ -1163,9 +1094,9 @@ var Sentry = (function (exports) {
1163
1094
  * @returns Answer to the given question.
1164
1095
  */
1165
1096
  function supportsReferrerPolicy() {
1166
- // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
1167
- // https://caniuse.com/#feat=referrer-policy
1168
- // It doesn't. And it throw exception instead of ignoring this parameter...
1097
+ // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
1098
+ // (see https://caniuse.com/#feat=referrer-policy),
1099
+ // it doesn't. And it throws an exception instead of ignoring this parameter...
1169
1100
  // REF: https://github.com/getsentry/raven-js/issues/1233
1170
1101
  if (!supportsFetch()) {
1171
1102
  return false;
@@ -1250,13 +1181,10 @@ var Sentry = (function (exports) {
1250
1181
  * Use at your own risk, this might break without changelog notice, only used internally.
1251
1182
  * @hidden
1252
1183
  */
1253
- function addInstrumentationHandler(handler) {
1254
- if (!handler || typeof handler.type !== 'string' || typeof handler.callback !== 'function') {
1255
- return;
1256
- }
1257
- handlers[handler.type] = handlers[handler.type] || [];
1258
- handlers[handler.type].push(handler.callback);
1259
- instrument(handler.type);
1184
+ function addInstrumentationHandler(type, callback) {
1185
+ handlers[type] = handlers[type] || [];
1186
+ handlers[type].push(callback);
1187
+ instrument(type);
1260
1188
  }
1261
1189
  /** JSDoc */
1262
1190
  function triggerHandlers(type, data) {
@@ -1268,7 +1196,9 @@ var Sentry = (function (exports) {
1268
1196
  handler(data);
1269
1197
  }
1270
1198
  catch (e) {
1271
- logger.error(`Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError: ${e}`);
1199
+ if (isDebugBuild()) {
1200
+ logger.error(`Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError: ${e}`);
1201
+ }
1272
1202
  }
1273
1203
  }
1274
1204
  }
@@ -1349,23 +1279,20 @@ var Sentry = (function (exports) {
1349
1279
  if (!('XMLHttpRequest' in global$2)) {
1350
1280
  return;
1351
1281
  }
1352
- // Poor man's implementation of ES6 `Map`, tracking and keeping in sync key and value separately.
1353
- const requestKeys = [];
1354
- const requestValues = [];
1355
1282
  const xhrproto = XMLHttpRequest.prototype;
1356
1283
  fill(xhrproto, 'open', function (originalOpen) {
1357
1284
  return function (...args) {
1358
1285
  // eslint-disable-next-line @typescript-eslint/no-this-alias
1359
1286
  const xhr = this;
1360
1287
  const url = args[1];
1361
- xhr.__sentry_xhr__ = {
1288
+ const xhrInfo = (xhr.__sentry_xhr__ = {
1362
1289
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1363
1290
  method: isString(args[0]) ? args[0].toUpperCase() : args[0],
1364
1291
  url: args[1],
1365
- };
1292
+ });
1366
1293
  // if Sentry key appears in URL, don't capture it as a request
1367
1294
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1368
- if (isString(url) && xhr.__sentry_xhr__.method === 'POST' && url.match(/sentry_key/)) {
1295
+ if (isString(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) {
1369
1296
  xhr.__sentry_own_request__ = true;
1370
1297
  }
1371
1298
  const onreadystatechangeHandler = function () {
@@ -1373,23 +1300,7 @@ var Sentry = (function (exports) {
1373
1300
  try {
1374
1301
  // touching statusCode in some platforms throws
1375
1302
  // an exception
1376
- if (xhr.__sentry_xhr__) {
1377
- xhr.__sentry_xhr__.status_code = xhr.status;
1378
- }
1379
- }
1380
- catch (e) {
1381
- /* do nothing */
1382
- }
1383
- try {
1384
- const requestPos = requestKeys.indexOf(xhr);
1385
- if (requestPos !== -1) {
1386
- // Make sure to pop both key and value to keep it in sync.
1387
- requestKeys.splice(requestPos);
1388
- const args = requestValues.splice(requestPos)[0];
1389
- if (xhr.__sentry_xhr__ && args[0] !== undefined) {
1390
- xhr.__sentry_xhr__.body = args[0];
1391
- }
1392
- }
1303
+ xhrInfo.status_code = xhr.status;
1393
1304
  }
1394
1305
  catch (e) {
1395
1306
  /* do nothing */
@@ -1418,8 +1329,9 @@ var Sentry = (function (exports) {
1418
1329
  });
1419
1330
  fill(xhrproto, 'send', function (originalSend) {
1420
1331
  return function (...args) {
1421
- requestKeys.push(this);
1422
- requestValues.push(args);
1332
+ if (this.__sentry_xhr__ && args[0] !== undefined) {
1333
+ this.__sentry_xhr__.body = args[0];
1334
+ }
1423
1335
  triggerHandlers('xhr', {
1424
1336
  args,
1425
1337
  startTimestamp: Date.now(),
@@ -1754,22 +1666,26 @@ var Sentry = (function (exports) {
1754
1666
  relative: match[5] + query + fragment,
1755
1667
  };
1756
1668
  }
1669
+ function getFirstException(event) {
1670
+ return event.exception && event.exception.values ? event.exception.values[0] : undefined;
1671
+ }
1757
1672
  /**
1758
1673
  * Extracts either message or type+value from an event that can be used for user-facing logs
1759
1674
  * @returns event's description
1760
1675
  */
1761
1676
  function getEventDescription(event) {
1762
- if (event.message) {
1763
- return event.message;
1677
+ const { message, event_id: eventId } = event;
1678
+ if (message) {
1679
+ return message;
1764
1680
  }
1765
- if (event.exception && event.exception.values && event.exception.values[0]) {
1766
- const exception = event.exception.values[0];
1767
- if (exception.type && exception.value) {
1768
- return `${exception.type}: ${exception.value}`;
1681
+ const firstException = getFirstException(event);
1682
+ if (firstException) {
1683
+ if (firstException.type && firstException.value) {
1684
+ return `${firstException.type}: ${firstException.value}`;
1769
1685
  }
1770
- return exception.type || exception.value || event.event_id || '<unknown>';
1686
+ return firstException.type || firstException.value || eventId || '<unknown>';
1771
1687
  }
1772
- return event.event_id || '<unknown>';
1688
+ return eventId || '<unknown>';
1773
1689
  }
1774
1690
  /**
1775
1691
  * Adds exception values, type and value to an synthetic Exception.
@@ -1779,11 +1695,15 @@ var Sentry = (function (exports) {
1779
1695
  * @hidden
1780
1696
  */
1781
1697
  function addExceptionTypeValue(event, value, type) {
1782
- event.exception = event.exception || {};
1783
- event.exception.values = event.exception.values || [];
1784
- event.exception.values[0] = event.exception.values[0] || {};
1785
- event.exception.values[0].value = event.exception.values[0].value || value || '';
1786
- event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
1698
+ const exception = (event.exception = event.exception || {});
1699
+ const values = (exception.values = exception.values || []);
1700
+ const firstException = (values[0] = values[0] || {});
1701
+ if (!firstException.value) {
1702
+ firstException.value = value || '';
1703
+ }
1704
+ if (!firstException.type) {
1705
+ firstException.type = type || 'Error';
1706
+ }
1787
1707
  }
1788
1708
  /**
1789
1709
  * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
@@ -1793,17 +1713,16 @@ var Sentry = (function (exports) {
1793
1713
  * @hidden
1794
1714
  */
1795
1715
  function addExceptionMechanism(event, newMechanism) {
1796
- var _a;
1797
- if (!event.exception || !event.exception.values) {
1716
+ const firstException = getFirstException(event);
1717
+ if (!firstException) {
1798
1718
  return;
1799
1719
  }
1800
- const exceptionValue0 = event.exception.values[0];
1801
1720
  const defaultMechanism = { type: 'generic', handled: true };
1802
- const currentMechanism = exceptionValue0.mechanism;
1803
- exceptionValue0.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
1721
+ const currentMechanism = firstException.mechanism;
1722
+ firstException.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
1804
1723
  if (newMechanism && 'data' in newMechanism) {
1805
- const mergedData = Object.assign(Object.assign({}, (_a = currentMechanism) === null || _a === void 0 ? void 0 : _a.data), newMechanism.data);
1806
- exceptionValue0.mechanism.data = mergedData;
1724
+ const mergedData = Object.assign(Object.assign({}, (currentMechanism && currentMechanism.data)), newMechanism.data);
1725
+ firstException.mechanism.data = mergedData;
1807
1726
  }
1808
1727
  }
1809
1728
  const defaultRetryAfter = 60 * 1000; // 60 seconds
@@ -1848,17 +1767,14 @@ var Sentry = (function (exports) {
1848
1767
  * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
1849
1768
  */
1850
1769
  function checkOrSetAlreadyCaught(exception) {
1851
- var _a;
1852
1770
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1853
- if ((_a = exception) === null || _a === void 0 ? void 0 : _a.__sentry_captured__) {
1771
+ if (exception && exception.__sentry_captured__) {
1854
1772
  return true;
1855
1773
  }
1856
1774
  try {
1857
1775
  // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
1858
1776
  // `ExtraErrorData` integration
1859
- Object.defineProperty(exception, '__sentry_captured__', {
1860
- value: true,
1861
- });
1777
+ addNonEnumerableProperty(exception, '__sentry_captured__', true);
1862
1778
  }
1863
1779
  catch (err) {
1864
1780
  // `exception` is a primitive, so we can't mark it seen
@@ -1867,35 +1783,47 @@ var Sentry = (function (exports) {
1867
1783
  }
1868
1784
 
1869
1785
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
1870
- /** SyncPromise internal states */
1871
- var States;
1872
- (function (States) {
1873
- /** Pending */
1874
- States["PENDING"] = "PENDING";
1875
- /** Resolved / OK */
1876
- States["RESOLVED"] = "RESOLVED";
1877
- /** Rejected / Error */
1878
- States["REJECTED"] = "REJECTED";
1879
- })(States || (States = {}));
1786
+ /**
1787
+ * Creates a resolved sync promise.
1788
+ *
1789
+ * @param value the value to resolve the promise with
1790
+ * @returns the resolved sync promise
1791
+ */
1792
+ function resolvedSyncPromise(value) {
1793
+ return new SyncPromise(resolve => {
1794
+ resolve(value);
1795
+ });
1796
+ }
1797
+ /**
1798
+ * Creates a rejected sync promise.
1799
+ *
1800
+ * @param value the value to reject the promise with
1801
+ * @returns the rejected sync promise
1802
+ */
1803
+ function rejectedSyncPromise(reason) {
1804
+ return new SyncPromise((_, reject) => {
1805
+ reject(reason);
1806
+ });
1807
+ }
1880
1808
  /**
1881
1809
  * Thenable class that behaves like a Promise and follows it's interface
1882
1810
  * but is not async internally
1883
1811
  */
1884
1812
  class SyncPromise {
1885
1813
  constructor(executor) {
1886
- this._state = States.PENDING;
1814
+ this._state = 0 /* PENDING */;
1887
1815
  this._handlers = [];
1888
1816
  /** JSDoc */
1889
1817
  this._resolve = (value) => {
1890
- this._setResult(States.RESOLVED, value);
1818
+ this._setResult(1 /* RESOLVED */, value);
1891
1819
  };
1892
1820
  /** JSDoc */
1893
1821
  this._reject = (reason) => {
1894
- this._setResult(States.REJECTED, reason);
1822
+ this._setResult(2 /* REJECTED */, reason);
1895
1823
  };
1896
1824
  /** JSDoc */
1897
1825
  this._setResult = (state, value) => {
1898
- if (this._state !== States.PENDING) {
1826
+ if (this._state !== 0 /* PENDING */) {
1899
1827
  return;
1900
1828
  }
1901
1829
  if (isThenable(value)) {
@@ -1906,35 +1834,25 @@ var Sentry = (function (exports) {
1906
1834
  this._value = value;
1907
1835
  this._executeHandlers();
1908
1836
  };
1909
- // TODO: FIXME
1910
- /** JSDoc */
1911
- this._attachHandler = (handler) => {
1912
- this._handlers = this._handlers.concat(handler);
1913
- this._executeHandlers();
1914
- };
1915
1837
  /** JSDoc */
1916
1838
  this._executeHandlers = () => {
1917
- if (this._state === States.PENDING) {
1839
+ if (this._state === 0 /* PENDING */) {
1918
1840
  return;
1919
1841
  }
1920
1842
  const cachedHandlers = this._handlers.slice();
1921
1843
  this._handlers = [];
1922
1844
  cachedHandlers.forEach(handler => {
1923
- if (handler.done) {
1845
+ if (handler[0]) {
1924
1846
  return;
1925
1847
  }
1926
- if (this._state === States.RESOLVED) {
1927
- if (handler.onfulfilled) {
1928
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1929
- handler.onfulfilled(this._value);
1930
- }
1848
+ if (this._state === 1 /* RESOLVED */) {
1849
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1850
+ handler[1](this._value);
1931
1851
  }
1932
- if (this._state === States.REJECTED) {
1933
- if (handler.onrejected) {
1934
- handler.onrejected(this._value);
1935
- }
1852
+ if (this._state === 2 /* REJECTED */) {
1853
+ handler[2](this._value);
1936
1854
  }
1937
- handler.done = true;
1855
+ handler[0] = true;
1938
1856
  });
1939
1857
  };
1940
1858
  try {
@@ -1945,80 +1863,40 @@ var Sentry = (function (exports) {
1945
1863
  }
1946
1864
  }
1947
1865
  /** JSDoc */
1948
- static resolve(value) {
1949
- return new SyncPromise(resolve => {
1950
- resolve(value);
1951
- });
1952
- }
1953
- /** JSDoc */
1954
- static reject(reason) {
1955
- return new SyncPromise((_, reject) => {
1956
- reject(reason);
1957
- });
1958
- }
1959
- /** JSDoc */
1960
- static all(collection) {
1961
- return new SyncPromise((resolve, reject) => {
1962
- if (!Array.isArray(collection)) {
1963
- reject(new TypeError(`Promise.all requires an array as input.`));
1964
- return;
1965
- }
1966
- if (collection.length === 0) {
1967
- resolve([]);
1968
- return;
1969
- }
1970
- let counter = collection.length;
1971
- const resolvedCollection = [];
1972
- collection.forEach((item, index) => {
1973
- void SyncPromise.resolve(item)
1974
- .then(value => {
1975
- resolvedCollection[index] = value;
1976
- counter -= 1;
1977
- if (counter !== 0) {
1978
- return;
1979
- }
1980
- resolve(resolvedCollection);
1981
- })
1982
- .then(null, reject);
1983
- });
1984
- });
1985
- }
1986
- /** JSDoc */
1987
1866
  then(onfulfilled, onrejected) {
1988
1867
  return new SyncPromise((resolve, reject) => {
1989
- this._attachHandler({
1990
- done: false,
1991
- onfulfilled: result => {
1868
+ this._handlers.push([
1869
+ false,
1870
+ result => {
1992
1871
  if (!onfulfilled) {
1993
1872
  // TODO: ¯\_(ツ)_/¯
1994
1873
  // TODO: FIXME
1995
1874
  resolve(result);
1996
- return;
1997
- }
1998
- try {
1999
- resolve(onfulfilled(result));
2000
- return;
2001
1875
  }
2002
- catch (e) {
2003
- reject(e);
2004
- return;
1876
+ else {
1877
+ try {
1878
+ resolve(onfulfilled(result));
1879
+ }
1880
+ catch (e) {
1881
+ reject(e);
1882
+ }
2005
1883
  }
2006
1884
  },
2007
- onrejected: reason => {
1885
+ reason => {
2008
1886
  if (!onrejected) {
2009
1887
  reject(reason);
2010
- return;
2011
1888
  }
2012
- try {
2013
- resolve(onrejected(reason));
2014
- return;
2015
- }
2016
- catch (e) {
2017
- reject(e);
2018
- return;
1889
+ else {
1890
+ try {
1891
+ resolve(onrejected(reason));
1892
+ }
1893
+ catch (e) {
1894
+ reject(e);
1895
+ }
2019
1896
  }
2020
1897
  },
2021
- });
1898
+ ]);
1899
+ this._executeHandlers();
2022
1900
  });
2023
1901
  }
2024
1902
  /** JSDoc */
@@ -2051,24 +1929,25 @@ var Sentry = (function (exports) {
2051
1929
  });
2052
1930
  });
2053
1931
  }
2054
- /** JSDoc */
2055
- toString() {
2056
- return '[object SyncPromise]';
2057
- }
2058
1932
  }
2059
1933
 
2060
- /** A simple queue that holds promises. */
2061
- class PromiseBuffer {
2062
- constructor(_limit) {
2063
- this._limit = _limit;
2064
- /** Internal set of queued Promises */
2065
- this._buffer = [];
1934
+ /**
1935
+ * Creates an new PromiseBuffer object with the specified limit
1936
+ * @param limit max number of promises that can be stored in the buffer
1937
+ */
1938
+ function makePromiseBuffer(limit) {
1939
+ const buffer = [];
1940
+ function isReady() {
1941
+ return limit === undefined || buffer.length < limit;
2066
1942
  }
2067
1943
  /**
2068
- * Says if the buffer is ready to take more requests
1944
+ * Remove a promise from the queue.
1945
+ *
1946
+ * @param task Can be any PromiseLike<T>
1947
+ * @returns Removed promise.
2069
1948
  */
2070
- isReady() {
2071
- return this._limit === undefined || this.length() < this._limit;
1949
+ function remove(task) {
1950
+ return buffer.splice(buffer.indexOf(task), 1)[0];
2072
1951
  }
2073
1952
  /**
2074
1953
  * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
@@ -2080,41 +1959,25 @@ var Sentry = (function (exports) {
2080
1959
  * limit check.
2081
1960
  * @returns The original promise.
2082
1961
  */
2083
- add(taskProducer) {
2084
- if (!this.isReady()) {
2085
- return SyncPromise.reject(new SentryError('Not adding Promise due to buffer limit reached.'));
1962
+ function add(taskProducer) {
1963
+ if (!isReady()) {
1964
+ return rejectedSyncPromise(new SentryError('Not adding Promise due to buffer limit reached.'));
2086
1965
  }
2087
1966
  // start the task and add its promise to the queue
2088
1967
  const task = taskProducer();
2089
- if (this._buffer.indexOf(task) === -1) {
2090
- this._buffer.push(task);
1968
+ if (buffer.indexOf(task) === -1) {
1969
+ buffer.push(task);
2091
1970
  }
2092
1971
  void task
2093
- .then(() => this.remove(task))
1972
+ .then(() => remove(task))
2094
1973
  // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
2095
1974
  // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
2096
1975
  // have promises, so TS has to polyfill when down-compiling.)
2097
- .then(null, () => this.remove(task).then(null, () => {
2098
- // We have to add another catch here because `this.remove()` starts a new promise chain.
1976
+ .then(null, () => remove(task).then(null, () => {
1977
+ // We have to add another catch here because `remove()` starts a new promise chain.
2099
1978
  }));
2100
1979
  return task;
2101
1980
  }
2102
- /**
2103
- * Remove a promise from the queue.
2104
- *
2105
- * @param task Can be any PromiseLike<T>
2106
- * @returns Removed promise.
2107
- */
2108
- remove(task) {
2109
- const removedTask = this._buffer.splice(this._buffer.indexOf(task), 1)[0];
2110
- return removedTask;
2111
- }
2112
- /**
2113
- * This function returns the number of unresolved promises in the queue.
2114
- */
2115
- length() {
2116
- return this._buffer.length;
2117
- }
2118
1981
  /**
2119
1982
  * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
2120
1983
  *
@@ -2124,8 +1987,12 @@ var Sentry = (function (exports) {
2124
1987
  * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
2125
1988
  * `false` otherwise
2126
1989
  */
2127
- drain(timeout) {
2128
- return new SyncPromise(resolve => {
1990
+ function drain(timeout) {
1991
+ return new SyncPromise((resolve, reject) => {
1992
+ let counter = buffer.length;
1993
+ if (!counter) {
1994
+ return resolve(true);
1995
+ }
2129
1996
  // wait for `timeout` ms and then resolve to `false` (if not cancelled first)
2130
1997
  const capturedSetTimeout = setTimeout(() => {
2131
1998
  if (timeout && timeout > 0) {
@@ -2133,16 +2000,62 @@ var Sentry = (function (exports) {
2133
2000
  }
2134
2001
  }, timeout);
2135
2002
  // if all promises resolve in time, cancel the timer and resolve to `true`
2136
- void SyncPromise.all(this._buffer)
2137
- .then(() => {
2138
- clearTimeout(capturedSetTimeout);
2139
- resolve(true);
2140
- })
2141
- .then(null, () => {
2142
- resolve(true);
2003
+ buffer.forEach(item => {
2004
+ void resolvedSyncPromise(item).then(() => {
2005
+ // eslint-disable-next-line no-plusplus
2006
+ if (!--counter) {
2007
+ clearTimeout(capturedSetTimeout);
2008
+ resolve(true);
2009
+ }
2010
+ }, reject);
2143
2011
  });
2144
2012
  });
2145
2013
  }
2014
+ return {
2015
+ $: buffer,
2016
+ add,
2017
+ drain,
2018
+ };
2019
+ }
2020
+
2021
+ function isSupportedSeverity(level) {
2022
+ return SeverityLevels.indexOf(level) !== -1;
2023
+ }
2024
+ /**
2025
+ * Converts a string-based level into a {@link Severity}.
2026
+ *
2027
+ * @param level string representation of Severity
2028
+ * @returns Severity
2029
+ */
2030
+ function severityFromString(level) {
2031
+ if (level === 'warn')
2032
+ return exports.Severity.Warning;
2033
+ if (isSupportedSeverity(level)) {
2034
+ return level;
2035
+ }
2036
+ return exports.Severity.Log;
2037
+ }
2038
+
2039
+ /**
2040
+ * Converts an HTTP status code to sentry status {@link EventStatus}.
2041
+ *
2042
+ * @param code number HTTP status code
2043
+ * @returns EventStatus
2044
+ */
2045
+ function eventStatusFromHttpCode(code) {
2046
+ if (code >= 200 && code < 300) {
2047
+ return 'success';
2048
+ }
2049
+ if (code === 429) {
2050
+ return 'rate_limit';
2051
+ }
2052
+ if (code >= 400 && code < 500) {
2053
+ return 'invalid';
2054
+ }
2055
+ if (code >= 500) {
2056
+ return 'failed';
2057
+ }
2058
+ return 'unknown';
2146
2059
  }
2147
2060
 
2148
2061
  /**
@@ -2301,6 +2214,11 @@ var Sentry = (function (exports) {
2301
2214
  this._extra = {};
2302
2215
  /** Contexts */
2303
2216
  this._contexts = {};
2217
+ /**
2218
+ * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
2219
+ * sent to Sentry
2220
+ */
2221
+ this._sdkProcessingMetadata = {};
2304
2222
  }
2305
2223
  /**
2306
2224
  * Inherit values from the parent scope.
@@ -2463,19 +2381,10 @@ var Sentry = (function (exports) {
2463
2381
  * @inheritDoc
2464
2382
  */
2465
2383
  getTransaction() {
2466
- var _a, _b, _c, _d;
2467
- // often, this span will be a transaction, but it's not guaranteed to be
2384
+ // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
2385
+ // have a pointer to the currently-active transaction.
2468
2386
  const span = this.getSpan();
2469
- // try it the new way first
2470
- if ((_a = span) === null || _a === void 0 ? void 0 : _a.transaction) {
2471
- return (_b = span) === null || _b === void 0 ? void 0 : _b.transaction;
2472
- }
2473
- // fallback to the old way (known bug: this only finds transactions with sampled = true)
2474
- if ((_d = (_c = span) === null || _c === void 0 ? void 0 : _c.spanRecorder) === null || _d === void 0 ? void 0 : _d.spans[0]) {
2475
- return span.spanRecorder.spans[0];
2476
- }
2477
- // neither way found a transaction
2478
- return undefined;
2387
+ return span && span.transaction;
2479
2388
  }
2480
2389
  /**
2481
2390
  * @inheritDoc
@@ -2594,7 +2503,6 @@ var Sentry = (function (exports) {
2594
2503
  * @hidden
2595
2504
  */
2596
2505
  applyToEvent(event, hint) {
2597
- var _a;
2598
2506
  if (this._extra && Object.keys(this._extra).length) {
2599
2507
  event.extra = Object.assign(Object.assign({}, this._extra), event.extra);
2600
2508
  }
@@ -2618,7 +2526,7 @@ var Sentry = (function (exports) {
2618
2526
  // errors with transaction and it relies on that.
2619
2527
  if (this._span) {
2620
2528
  event.contexts = Object.assign({ trace: this._span.getTraceContext() }, event.contexts);
2621
- const transactionName = (_a = this._span.transaction) === null || _a === void 0 ? void 0 : _a.name;
2529
+ const transactionName = this._span.transaction && this._span.transaction.name;
2622
2530
  if (transactionName) {
2623
2531
  event.tags = Object.assign({ transaction: transactionName }, event.tags);
2624
2532
  }
@@ -2626,8 +2534,16 @@ var Sentry = (function (exports) {
2626
2534
  this._applyFingerprint(event);
2627
2535
  event.breadcrumbs = [...(event.breadcrumbs || []), ...this._breadcrumbs];
2628
2536
  event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
2537
+ event.sdkProcessingMetadata = this._sdkProcessingMetadata;
2629
2538
  return this._notifyEventProcessors([...getGlobalEventProcessors(), ...this._eventProcessors], event, hint);
2630
2539
  }
2540
+ /**
2541
+ * Add data which will be accessible during event processing but won't get sent to Sentry
2542
+ */
2543
+ setSDKProcessingMetadata(newData) {
2544
+ this._sdkProcessingMetadata = Object.assign(Object.assign({}, this._sdkProcessingMetadata), newData);
2545
+ return this;
2546
+ }
2631
2547
  /**
2632
2548
  * This will be called after {@link applyToEvent} is finished.
2633
2549
  */
@@ -2715,7 +2631,7 @@ var Sentry = (function (exports) {
2715
2631
  this.errors = 0;
2716
2632
  this.sid = uuid4();
2717
2633
  this.duration = 0;
2718
- this.status = SessionStatus.Ok;
2634
+ this.status = 'ok';
2719
2635
  this.init = true;
2720
2636
  this.ignoreDuration = false;
2721
2637
  // Both timestamp and started are in seconds since the UNIX epoch.
@@ -2788,8 +2704,8 @@ var Sentry = (function (exports) {
2788
2704
  if (status) {
2789
2705
  this.update({ status });
2790
2706
  }
2791
- else if (this.status === SessionStatus.Ok) {
2792
- this.update({ status: SessionStatus.Exited });
2707
+ else if (this.status === 'ok') {
2708
+ this.update({ status: 'exited' });
2793
2709
  }
2794
2710
  else {
2795
2711
  this.update();
@@ -2807,17 +2723,16 @@ var Sentry = (function (exports) {
2807
2723
  errors: this.errors,
2808
2724
  did: typeof this.did === 'number' || typeof this.did === 'string' ? `${this.did}` : undefined,
2809
2725
  duration: this.duration,
2810
- attrs: dropUndefinedKeys({
2726
+ attrs: {
2811
2727
  release: this.release,
2812
2728
  environment: this.environment,
2813
2729
  ip_address: this.ipAddress,
2814
2730
  user_agent: this.userAgent,
2815
- }),
2731
+ },
2816
2732
  });
2817
2733
  }
2818
2734
  }
2819
2735
 
2820
- /* eslint-disable max-lines */
2821
2736
  /**
2822
2737
  * API compatibility version of this hub.
2823
2738
  *
@@ -3127,11 +3042,17 @@ var Sentry = (function (exports) {
3127
3042
  * @inheritDoc
3128
3043
  */
3129
3044
  endSession() {
3130
- var _a, _b, _c, _d, _e;
3131
- (_c = (_b = (_a = this.getStackTop()) === null || _a === void 0 ? void 0 : _a.scope) === null || _b === void 0 ? void 0 : _b.getSession()) === null || _c === void 0 ? void 0 : _c.close();
3045
+ const layer = this.getStackTop();
3046
+ const scope = layer && layer.scope;
3047
+ const session = scope && scope.getSession();
3048
+ if (session) {
3049
+ session.close();
3050
+ }
3132
3051
  this._sendSessionUpdate();
3133
3052
  // the session is over; take it off of the scope
3134
- (_e = (_d = this.getStackTop()) === null || _d === void 0 ? void 0 : _d.scope) === null || _e === void 0 ? void 0 : _e.setSession();
3053
+ if (scope) {
3054
+ scope.setSession();
3055
+ }
3135
3056
  }
3136
3057
  /**
3137
3058
  * @inheritDoc
@@ -3147,8 +3068,8 @@ var Sentry = (function (exports) {
3147
3068
  if (scope) {
3148
3069
  // End existing session if there's one
3149
3070
  const currentSession = scope.getSession && scope.getSession();
3150
- if (currentSession && currentSession.status === SessionStatus.Ok) {
3151
- currentSession.update({ status: SessionStatus.Exited });
3071
+ if (currentSession && currentSession.status === 'ok') {
3072
+ currentSession.update({ status: 'exited' });
3152
3073
  }
3153
3074
  this.endSession();
3154
3075
  // Afterwards we set the new session on the scope
@@ -3250,9 +3171,9 @@ var Sentry = (function (exports) {
3250
3171
  * @returns discovered hub
3251
3172
  */
3252
3173
  function getHubFromActiveDomain(registry) {
3253
- var _a, _b, _c;
3254
3174
  try {
3255
- const activeDomain = (_c = (_b = (_a = getMainCarrier().__SENTRY__) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.domain) === null || _c === void 0 ? void 0 : _c.active;
3175
+ const sentry = getMainCarrier().__SENTRY__;
3176
+ const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
3256
3177
  // If there's no active domain, just return global hub
3257
3178
  if (!activeDomain) {
3258
3179
  return getHubFromCarrier(registry);
@@ -3343,7 +3264,7 @@ var Sentry = (function (exports) {
3343
3264
  * Captures a message event and sends it to Sentry.
3344
3265
  *
3345
3266
  * @param message The message to send to Sentry.
3346
- * @param level Define the level of the message.
3267
+ * @param Severity Define the level of the message.
3347
3268
  * @returns The generated eventId.
3348
3269
  */
3349
3270
  function captureMessage(message, captureContext) {
@@ -3475,134 +3396,83 @@ var Sentry = (function (exports) {
3475
3396
  }
3476
3397
 
3477
3398
  const SENTRY_API_VERSION = '7';
3399
+ /** Initializes API Details */
3400
+ function initAPIDetails(dsn, metadata, tunnel) {
3401
+ return {
3402
+ initDsn: dsn,
3403
+ metadata: metadata || {},
3404
+ dsn: makeDsn(dsn),
3405
+ tunnel,
3406
+ };
3407
+ }
3408
+ /** Returns the prefix to construct Sentry ingestion API endpoints. */
3409
+ function getBaseApiEndpoint(dsn) {
3410
+ const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
3411
+ const port = dsn.port ? `:${dsn.port}` : '';
3412
+ return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
3413
+ }
3414
+ /** Returns the ingest API endpoint for target. */
3415
+ function _getIngestEndpoint(dsn, target) {
3416
+ return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/${target}/`;
3417
+ }
3418
+ /** Returns a URL-encoded string with auth config suitable for a query string. */
3419
+ function _encodedAuth(dsn) {
3420
+ return urlEncode({
3421
+ // We send only the minimum set of required information. See
3422
+ // https://github.com/getsentry/sentry-javascript/issues/2572.
3423
+ sentry_key: dsn.publicKey,
3424
+ sentry_version: SENTRY_API_VERSION,
3425
+ });
3426
+ }
3427
+ /** Returns the store endpoint URL. */
3428
+ function getStoreEndpoint(dsn) {
3429
+ return _getIngestEndpoint(dsn, 'store');
3430
+ }
3478
3431
  /**
3479
- * Helper class to provide urls, headers and metadata that can be used to form
3480
- * different types of requests to Sentry endpoints.
3481
- * Supports both envelopes and regular event requests.
3482
- **/
3483
- class API {
3484
- /** Create a new instance of API */
3485
- constructor(dsn, metadata = {}, tunnel) {
3486
- this.dsn = dsn;
3487
- this._dsnObject = new Dsn(dsn);
3488
- this.metadata = metadata;
3489
- this._tunnel = tunnel;
3490
- }
3491
- /** Returns the Dsn object. */
3492
- getDsn() {
3493
- return this._dsnObject;
3494
- }
3495
- /** Does this transport force envelopes? */
3496
- forceEnvelope() {
3497
- return !!this._tunnel;
3498
- }
3499
- /** Returns the prefix to construct Sentry ingestion API endpoints. */
3500
- getBaseApiEndpoint() {
3501
- const dsn = this.getDsn();
3502
- const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
3503
- const port = dsn.port ? `:${dsn.port}` : '';
3504
- return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
3505
- }
3506
- /** Returns the store endpoint URL. */
3507
- getStoreEndpoint() {
3508
- return this._getIngestEndpoint('store');
3509
- }
3510
- /**
3511
- * Returns the store endpoint URL with auth in the query string.
3512
- *
3513
- * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3514
- */
3515
- getStoreEndpointWithUrlEncodedAuth() {
3516
- return `${this.getStoreEndpoint()}?${this._encodedAuth()}`;
3517
- }
3518
- /**
3519
- * Returns the envelope endpoint URL with auth in the query string.
3520
- *
3521
- * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3522
- */
3523
- getEnvelopeEndpointWithUrlEncodedAuth() {
3524
- if (this.forceEnvelope()) {
3525
- return this._tunnel;
3526
- }
3527
- return `${this._getEnvelopeEndpoint()}?${this._encodedAuth()}`;
3528
- }
3529
- /** Returns only the path component for the store endpoint. */
3530
- getStoreEndpointPath() {
3531
- const dsn = this.getDsn();
3532
- return `${dsn.path ? `/${dsn.path}` : ''}/api/${dsn.projectId}/store/`;
3533
- }
3534
- /**
3535
- * Returns an object that can be used in request headers.
3536
- * This is needed for node and the old /store endpoint in sentry
3537
- */
3538
- getRequestHeaders(clientName, clientVersion) {
3539
- // CHANGE THIS to use metadata but keep clientName and clientVersion compatible
3540
- const dsn = this.getDsn();
3541
- const header = [`Sentry sentry_version=${SENTRY_API_VERSION}`];
3542
- header.push(`sentry_client=${clientName}/${clientVersion}`);
3543
- header.push(`sentry_key=${dsn.publicKey}`);
3544
- if (dsn.pass) {
3545
- header.push(`sentry_secret=${dsn.pass}`);
3432
+ * Returns the store endpoint URL with auth in the query string.
3433
+ *
3434
+ * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3435
+ */
3436
+ function getStoreEndpointWithUrlEncodedAuth(dsn) {
3437
+ return `${getStoreEndpoint(dsn)}?${_encodedAuth(dsn)}`;
3438
+ }
3439
+ /** Returns the envelope endpoint URL. */
3440
+ function _getEnvelopeEndpoint(dsn) {
3441
+ return _getIngestEndpoint(dsn, 'envelope');
3442
+ }
3443
+ /**
3444
+ * Returns the envelope endpoint URL with auth in the query string.
3445
+ *
3446
+ * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3447
+ */
3448
+ function getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel) {
3449
+ return tunnel ? tunnel : `${_getEnvelopeEndpoint(dsn)}?${_encodedAuth(dsn)}`;
3450
+ }
3451
+ /** Returns the url to the report dialog endpoint. */
3452
+ function getReportDialogEndpoint(dsnLike, dialogOptions) {
3453
+ const dsn = makeDsn(dsnLike);
3454
+ const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
3455
+ let encodedOptions = `dsn=${dsnToString(dsn)}`;
3456
+ for (const key in dialogOptions) {
3457
+ if (key === 'dsn') {
3458
+ continue;
3546
3459
  }
3547
- return {
3548
- 'Content-Type': 'application/json',
3549
- 'X-Sentry-Auth': header.join(', '),
3550
- };
3551
- }
3552
- /** Returns the url to the report dialog endpoint. */
3553
- getReportDialogEndpoint(dialogOptions = {}) {
3554
- const dsn = this.getDsn();
3555
- const endpoint = `${this.getBaseApiEndpoint()}embed/error-page/`;
3556
- const encodedOptions = [];
3557
- encodedOptions.push(`dsn=${dsn.toString()}`);
3558
- for (const key in dialogOptions) {
3559
- if (key === 'dsn') {
3460
+ if (key === 'user') {
3461
+ if (!dialogOptions.user) {
3560
3462
  continue;
3561
3463
  }
3562
- if (key === 'user') {
3563
- if (!dialogOptions.user) {
3564
- continue;
3565
- }
3566
- if (dialogOptions.user.name) {
3567
- encodedOptions.push(`name=${encodeURIComponent(dialogOptions.user.name)}`);
3568
- }
3569
- if (dialogOptions.user.email) {
3570
- encodedOptions.push(`email=${encodeURIComponent(dialogOptions.user.email)}`);
3571
- }
3464
+ if (dialogOptions.user.name) {
3465
+ encodedOptions += `&name=${encodeURIComponent(dialogOptions.user.name)}`;
3572
3466
  }
3573
- else {
3574
- encodedOptions.push(`${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key])}`);
3467
+ if (dialogOptions.user.email) {
3468
+ encodedOptions += `&email=${encodeURIComponent(dialogOptions.user.email)}`;
3575
3469
  }
3576
3470
  }
3577
- if (encodedOptions.length) {
3578
- return `${endpoint}?${encodedOptions.join('&')}`;
3579
- }
3580
- return endpoint;
3581
- }
3582
- /** Returns the envelope endpoint URL. */
3583
- _getEnvelopeEndpoint() {
3584
- return this._getIngestEndpoint('envelope');
3585
- }
3586
- /** Returns the ingest API endpoint for target. */
3587
- _getIngestEndpoint(target) {
3588
- if (this._tunnel) {
3589
- return this._tunnel;
3471
+ else {
3472
+ encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key])}`;
3590
3473
  }
3591
- const base = this.getBaseApiEndpoint();
3592
- const dsn = this.getDsn();
3593
- return `${base}${dsn.projectId}/${target}/`;
3594
- }
3595
- /** Returns a URL-encoded string with auth config suitable for a query string. */
3596
- _encodedAuth() {
3597
- const dsn = this.getDsn();
3598
- const auth = {
3599
- // We send only the minimum set of required information. See
3600
- // https://github.com/getsentry/sentry-javascript/issues/2572.
3601
- sentry_key: dsn.publicKey,
3602
- sentry_version: SENTRY_API_VERSION,
3603
- };
3604
- return urlEncode(auth);
3605
3474
  }
3475
+ return `${endpoint}?${encodedOptions}`;
3606
3476
  }
3607
3477
 
3608
3478
  const installedIntegrations = [];
@@ -3666,7 +3536,7 @@ var Sentry = (function (exports) {
3666
3536
  // set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty`
3667
3537
  // because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be
3668
3538
  // considered a member of the index the way the actual integrations are
3669
- Object.defineProperty(integrations, 'initialized', { value: true });
3539
+ addNonEnumerableProperty(integrations, 'initialized', true);
3670
3540
  return integrations;
3671
3541
  }
3672
3542
 
@@ -3719,7 +3589,7 @@ var Sentry = (function (exports) {
3719
3589
  this._backend = new backendClass(options);
3720
3590
  this._options = options;
3721
3591
  if (options.dsn) {
3722
- this._dsn = new Dsn(options.dsn);
3592
+ this._dsn = makeDsn(options.dsn);
3723
3593
  }
3724
3594
  }
3725
3595
  /**
@@ -3760,9 +3630,8 @@ var Sentry = (function (exports) {
3760
3630
  * @inheritDoc
3761
3631
  */
3762
3632
  captureEvent(event, hint, scope) {
3763
- var _a;
3764
3633
  // ensure we haven't captured this very object before
3765
- if (((_a = hint) === null || _a === void 0 ? void 0 : _a.originalException) && checkOrSetAlreadyCaught(hint.originalException)) {
3634
+ if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {
3766
3635
  logger.log(ALREADY_SEEN_ERROR);
3767
3636
  return;
3768
3637
  }
@@ -3777,11 +3646,15 @@ var Sentry = (function (exports) {
3777
3646
  */
3778
3647
  captureSession(session) {
3779
3648
  if (!this._isEnabled()) {
3780
- logger.warn('SDK not enabled, will not capture session.');
3649
+ if (isDebugBuild()) {
3650
+ logger.warn('SDK not enabled, will not capture session.');
3651
+ }
3781
3652
  return;
3782
3653
  }
3783
3654
  if (!(typeof session.release === 'string')) {
3784
- logger.warn('Discarded session because of missing or non-string release');
3655
+ if (isDebugBuild()) {
3656
+ logger.warn('Discarded session because of missing or non-string release');
3657
+ }
3785
3658
  }
3786
3659
  else {
3787
3660
  this._sendSession(session);
@@ -3864,10 +3737,10 @@ var Sentry = (function (exports) {
3864
3737
  // A session is updated and that session update is sent in only one of the two following scenarios:
3865
3738
  // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
3866
3739
  // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
3867
- const sessionNonTerminal = session.status === SessionStatus.Ok;
3740
+ const sessionNonTerminal = session.status === 'ok';
3868
3741
  const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
3869
3742
  if (shouldUpdateAndSend) {
3870
- session.update(Object.assign(Object.assign({}, (crashed && { status: SessionStatus.Crashed })), { errors: session.errors || Number(errored || crashed) }));
3743
+ session.update(Object.assign(Object.assign({}, (crashed && { status: 'crashed' })), { errors: session.errors || Number(errored || crashed) }));
3871
3744
  this.captureSession(session);
3872
3745
  }
3873
3746
  }
@@ -3938,7 +3811,7 @@ var Sentry = (function (exports) {
3938
3811
  finalScope = Scope.clone(finalScope).update(hint.captureContext);
3939
3812
  }
3940
3813
  // We prepare the result here with a resolved Event.
3941
- let result = SyncPromise.resolve(prepared);
3814
+ let result = resolvedSyncPromise(prepared);
3942
3815
  // This should be the last thing called, since we want that
3943
3816
  // {@link Hub.addEventProcessor} gets the finished prepared event.
3944
3817
  if (finalScope) {
@@ -4070,26 +3943,29 @@ var Sentry = (function (exports) {
4070
3943
  * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
4071
3944
  */
4072
3945
  _processEvent(event, hint, scope) {
4073
- var _a, _b;
4074
3946
  // eslint-disable-next-line @typescript-eslint/unbound-method
4075
3947
  const { beforeSend, sampleRate } = this.getOptions();
4076
3948
  const transport = this.getTransport();
3949
+ function recordLostEvent(outcome, category) {
3950
+ if (transport.recordLostEvent) {
3951
+ transport.recordLostEvent(outcome, category);
3952
+ }
3953
+ }
4077
3954
  if (!this._isEnabled()) {
4078
- return SyncPromise.reject(new SentryError('SDK not enabled, will not capture event.'));
3955
+ return rejectedSyncPromise(new SentryError('SDK not enabled, will not capture event.'));
4079
3956
  }
4080
3957
  const isTransaction = event.type === 'transaction';
4081
3958
  // 1.0 === 100% events are sent
4082
3959
  // 0.0 === 0% events are sent
4083
3960
  // Sampling for transaction happens somewhere else
4084
3961
  if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) {
4085
- (_b = (_a = transport).recordLostEvent) === null || _b === void 0 ? void 0 : _b.call(_a, Outcome.SampleRate, 'event');
4086
- return SyncPromise.reject(new SentryError(`Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`));
3962
+ recordLostEvent('sample_rate', 'event');
3963
+ return rejectedSyncPromise(new SentryError(`Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`));
4087
3964
  }
4088
3965
  return this._prepareEvent(event, scope, hint)
4089
3966
  .then(prepared => {
4090
- var _a, _b;
4091
3967
  if (prepared === null) {
4092
- (_b = (_a = transport).recordLostEvent) === null || _b === void 0 ? void 0 : _b.call(_a, Outcome.EventProcessor, event.type || 'event');
3968
+ recordLostEvent('event_processor', event.type || 'event');
4093
3969
  throw new SentryError('An event processor returned null, will not send event.');
4094
3970
  }
4095
3971
  const isInternalException = hint && hint.data && hint.data.__sentry__ === true;
@@ -4097,12 +3973,11 @@ var Sentry = (function (exports) {
4097
3973
  return prepared;
4098
3974
  }
4099
3975
  const beforeSendResult = beforeSend(prepared, hint);
4100
- return this._ensureBeforeSendRv(beforeSendResult);
3976
+ return _ensureBeforeSendRv(beforeSendResult);
4101
3977
  })
4102
3978
  .then(processedEvent => {
4103
- var _a, _b;
4104
3979
  if (processedEvent === null) {
4105
- (_b = (_a = transport).recordLostEvent) === null || _b === void 0 ? void 0 : _b.call(_a, Outcome.BeforeSend, event.type || 'event');
3980
+ recordLostEvent('before_send', event.type || 'event');
4106
3981
  throw new SentryError('`beforeSend` returned `null`, will not send event.');
4107
3982
  }
4108
3983
  const session = scope && scope.getSession && scope.getSession();
@@ -4138,26 +4013,26 @@ var Sentry = (function (exports) {
4138
4013
  return reason;
4139
4014
  });
4140
4015
  }
4141
- /**
4142
- * Verifies that return value of configured `beforeSend` is of expected type.
4143
- */
4144
- _ensureBeforeSendRv(rv) {
4145
- const nullErr = '`beforeSend` method has to return `null` or a valid event.';
4146
- if (isThenable(rv)) {
4147
- return rv.then(event => {
4148
- if (!(isPlainObject(event) || event === null)) {
4149
- throw new SentryError(nullErr);
4150
- }
4151
- return event;
4152
- }, e => {
4153
- throw new SentryError(`beforeSend rejected with ${e}`);
4154
- });
4155
- }
4156
- else if (!(isPlainObject(rv) || rv === null)) {
4157
- throw new SentryError(nullErr);
4158
- }
4159
- return rv;
4016
+ }
4017
+ /**
4018
+ * Verifies that return value of configured `beforeSend` is of expected type.
4019
+ */
4020
+ function _ensureBeforeSendRv(rv) {
4021
+ const nullErr = '`beforeSend` method has to return `null` or a valid event.';
4022
+ if (isThenable(rv)) {
4023
+ return rv.then(event => {
4024
+ if (!(isPlainObject(event) || event === null)) {
4025
+ throw new SentryError(nullErr);
4026
+ }
4027
+ return event;
4028
+ }, e => {
4029
+ throw new SentryError(`beforeSend rejected with ${e}`);
4030
+ });
4160
4031
  }
4032
+ else if (!(isPlainObject(rv) || rv === null)) {
4033
+ throw new SentryError(nullErr);
4034
+ }
4035
+ return rv;
4161
4036
  }
4162
4037
 
4163
4038
  /** Noop transport */
@@ -4166,16 +4041,16 @@ var Sentry = (function (exports) {
4166
4041
  * @inheritDoc
4167
4042
  */
4168
4043
  sendEvent(_) {
4169
- return SyncPromise.resolve({
4044
+ return resolvedSyncPromise({
4170
4045
  reason: `NoopTransport: Event has been skipped because no Dsn is configured.`,
4171
- status: exports.Status.Skipped,
4046
+ status: 'skipped',
4172
4047
  });
4173
4048
  }
4174
4049
  /**
4175
4050
  * @inheritDoc
4176
4051
  */
4177
4052
  close(_) {
4178
- return SyncPromise.resolve(true);
4053
+ return resolvedSyncPromise(true);
4179
4054
  }
4180
4055
  }
4181
4056
 
@@ -4210,7 +4085,9 @@ var Sentry = (function (exports) {
4210
4085
  */
4211
4086
  sendEvent(event) {
4212
4087
  void this._transport.sendEvent(event).then(null, reason => {
4213
- logger.error(`Error while sending event: ${reason}`);
4088
+ if (isDebugBuild()) {
4089
+ logger.error(`Error while sending event: ${reason}`);
4090
+ }
4214
4091
  });
4215
4092
  }
4216
4093
  /**
@@ -4218,11 +4095,15 @@ var Sentry = (function (exports) {
4218
4095
  */
4219
4096
  sendSession(session) {
4220
4097
  if (!this._transport.sendSession) {
4221
- logger.warn("Dropping session because custom transport doesn't implement sendSession");
4098
+ if (isDebugBuild()) {
4099
+ logger.warn("Dropping session because custom transport doesn't implement sendSession");
4100
+ }
4222
4101
  return;
4223
4102
  }
4224
4103
  void this._transport.sendSession(session).then(null, reason => {
4225
- logger.error(`Error while sending session: ${reason}`);
4104
+ if (isDebugBuild()) {
4105
+ logger.error(`Error while sending session: ${reason}`);
4106
+ }
4226
4107
  });
4227
4108
  }
4228
4109
  /**
@@ -4239,31 +4120,6 @@ var Sentry = (function (exports) {
4239
4120
  }
4240
4121
  }
4241
4122
 
4242
- /*! *****************************************************************************
4243
- Copyright (c) Microsoft Corporation. All rights reserved.
4244
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4245
- this file except in compliance with the License. You may obtain a copy of the
4246
- License at http://www.apache.org/licenses/LICENSE-2.0
4247
-
4248
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4249
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
4250
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
4251
- MERCHANTABLITY OR NON-INFRINGEMENT.
4252
-
4253
- See the Apache Version 2.0 License for specific language governing permissions
4254
- and limitations under the License.
4255
- ***************************************************************************** */
4256
-
4257
- function __rest(s, e) {
4258
- var t = {};
4259
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4260
- t[p] = s[p];
4261
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
4262
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
4263
- t[p[i]] = s[p[i]];
4264
- return t;
4265
- }
4266
-
4267
4123
  /** Extract sdk info from from the API metadata */
4268
4124
  function getSdkMetadataForEnvelopeHeader(api) {
4269
4125
  if (!api.metadata || !api.metadata.sdk) {
@@ -4290,7 +4146,7 @@ var Sentry = (function (exports) {
4290
4146
  /** Creates a SentryRequest from a Session. */
4291
4147
  function sessionToSentryRequest(session, api) {
4292
4148
  const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
4293
- const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.forceEnvelope() && { dsn: api.getDsn().toString() })));
4149
+ const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
4294
4150
  // I know this is hacky but we don't want to add `session` to request type since it's never rate limited
4295
4151
  const type = 'aggregates' in session ? 'sessions' : 'session';
4296
4152
  const itemHeaders = JSON.stringify({
@@ -4299,26 +4155,24 @@ var Sentry = (function (exports) {
4299
4155
  return {
4300
4156
  body: `${envelopeHeaders}\n${itemHeaders}\n${JSON.stringify(session)}`,
4301
4157
  type,
4302
- url: api.getEnvelopeEndpointWithUrlEncodedAuth(),
4158
+ url: getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel),
4303
4159
  };
4304
4160
  }
4305
4161
  /** Creates a SentryRequest from an event. */
4306
4162
  function eventToSentryRequest(event, api) {
4307
4163
  const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
4308
4164
  const eventType = event.type || 'event';
4309
- const useEnvelope = eventType === 'transaction' || api.forceEnvelope();
4310
- const _a = event.debug_meta || {}, { transactionSampling } = _a, metadata = __rest(_a, ["transactionSampling"]);
4165
+ const useEnvelope = eventType === 'transaction' || !!api.tunnel;
4166
+ const { transactionSampling } = event.sdkProcessingMetadata || {};
4311
4167
  const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
4312
- if (Object.keys(metadata).length === 0) {
4313
- delete event.debug_meta;
4314
- }
4315
- else {
4316
- event.debug_meta = metadata;
4317
- }
4168
+ // prevent this data from being sent to sentry
4169
+ delete event.sdkProcessingMetadata;
4318
4170
  const req = {
4319
4171
  body: JSON.stringify(sdkInfo ? enhanceEventWithSdkInfo(event, api.metadata.sdk) : event),
4320
4172
  type: eventType,
4321
- url: useEnvelope ? api.getEnvelopeEndpointWithUrlEncodedAuth() : api.getStoreEndpointWithUrlEncodedAuth(),
4173
+ url: useEnvelope
4174
+ ? getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel)
4175
+ : getStoreEndpointWithUrlEncodedAuth(api.dsn),
4322
4176
  };
4323
4177
  // https://develop.sentry.dev/sdk/envelopes/
4324
4178
  // Since we don't need to manipulate envelopes nor store them, there is no
@@ -4326,7 +4180,7 @@ var Sentry = (function (exports) {
4326
4180
  // deserialization. Instead, we only implement a minimal subset of the spec to
4327
4181
  // serialize events inline here.
4328
4182
  if (useEnvelope) {
4329
- const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.forceEnvelope() && { dsn: api.getDsn().toString() })));
4183
+ const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
4330
4184
  const itemHeaders = JSON.stringify({
4331
4185
  type: eventType,
4332
4186
  // TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
@@ -4351,17 +4205,19 @@ var Sentry = (function (exports) {
4351
4205
  * @param options Options to pass to the client.
4352
4206
  */
4353
4207
  function initAndBind(clientClass, options) {
4354
- var _a;
4355
4208
  if (options.debug === true) {
4356
4209
  logger.enable();
4357
4210
  }
4358
4211
  const hub = getCurrentHub();
4359
- (_a = hub.getScope()) === null || _a === void 0 ? void 0 : _a.update(options.initialScope);
4212
+ const scope = hub.getScope();
4213
+ if (scope) {
4214
+ scope.update(options.initialScope);
4215
+ }
4360
4216
  const client = new clientClass(options);
4361
4217
  hub.bindClient(client);
4362
4218
  }
4363
4219
 
4364
- const SDK_VERSION = '6.15.0';
4220
+ const SDK_VERSION = '6.17.0';
4365
4221
 
4366
4222
  let originalFunctionToString;
4367
4223
  /** Patch toString calls to return proper name for wrapped functions */
@@ -4380,7 +4236,7 @@ var Sentry = (function (exports) {
4380
4236
  originalFunctionToString = Function.prototype.toString;
4381
4237
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4382
4238
  Function.prototype.toString = function (...args) {
4383
- const context = this.__sentry_original__ || this;
4239
+ const context = getOriginalFunction(this) || this;
4384
4240
  return originalFunctionToString.apply(context, args);
4385
4241
  };
4386
4242
  }
@@ -4432,19 +4288,27 @@ var Sentry = (function (exports) {
4432
4288
  /** JSDoc */
4433
4289
  _shouldDropEvent(event, options) {
4434
4290
  if (this._isSentryError(event, options)) {
4435
- logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
4291
+ if (isDebugBuild()) {
4292
+ logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
4293
+ }
4436
4294
  return true;
4437
4295
  }
4438
4296
  if (this._isIgnoredError(event, options)) {
4439
- logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
4297
+ if (isDebugBuild()) {
4298
+ logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
4299
+ }
4440
4300
  return true;
4441
4301
  }
4442
4302
  if (this._isDeniedUrl(event, options)) {
4443
- logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
4303
+ if (isDebugBuild()) {
4304
+ logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
4305
+ }
4444
4306
  return true;
4445
4307
  }
4446
4308
  if (!this._isAllowedUrl(event, options)) {
4447
- logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
4309
+ if (isDebugBuild()) {
4310
+ logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
4311
+ }
4448
4312
  return true;
4449
4313
  }
4450
4314
  return false;
@@ -4455,16 +4319,14 @@ var Sentry = (function (exports) {
4455
4319
  return false;
4456
4320
  }
4457
4321
  try {
4458
- return ((event &&
4459
- event.exception &&
4460
- event.exception.values &&
4461
- event.exception.values[0] &&
4462
- event.exception.values[0].type === 'SentryError') ||
4463
- false);
4322
+ // @ts-ignore can't be a sentry error if undefined
4323
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
4324
+ return event.exception.values[0].type === 'SentryError';
4464
4325
  }
4465
- catch (_oO) {
4466
- return false;
4326
+ catch (e) {
4327
+ // ignore
4467
4328
  }
4329
+ return false;
4468
4330
  }
4469
4331
  /** JSDoc */
4470
4332
  _isIgnoredError(event, options) {
@@ -4531,7 +4393,9 @@ var Sentry = (function (exports) {
4531
4393
  return [`${value}`, `${type}: ${value}`];
4532
4394
  }
4533
4395
  catch (oO) {
4534
- logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
4396
+ if (isDebugBuild()) {
4397
+ logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
4398
+ }
4535
4399
  return [];
4536
4400
  }
4537
4401
  }
@@ -4539,10 +4403,9 @@ var Sentry = (function (exports) {
4539
4403
  }
4540
4404
  /** JSDoc */
4541
4405
  _getLastValidUrl(frames = []) {
4542
- var _a, _b;
4543
4406
  for (let i = frames.length - 1; i >= 0; i--) {
4544
4407
  const frame = frames[i];
4545
- if (((_a = frame) === null || _a === void 0 ? void 0 : _a.filename) !== '<anonymous>' && ((_b = frame) === null || _b === void 0 ? void 0 : _b.filename) !== '[native code]') {
4408
+ if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
4546
4409
  return frame.filename || null;
4547
4410
  }
4548
4411
  }
@@ -4552,17 +4415,22 @@ var Sentry = (function (exports) {
4552
4415
  _getEventFilterUrl(event) {
4553
4416
  try {
4554
4417
  if (event.stacktrace) {
4555
- const frames = event.stacktrace.frames;
4556
- return this._getLastValidUrl(frames);
4418
+ return this._getLastValidUrl(event.stacktrace.frames);
4557
4419
  }
4558
- if (event.exception) {
4559
- const frames = event.exception.values && event.exception.values[0].stacktrace && event.exception.values[0].stacktrace.frames;
4560
- return this._getLastValidUrl(frames);
4420
+ let frames;
4421
+ try {
4422
+ // @ts-ignore we only care about frames if the whole thing here is defined
4423
+ frames = event.exception.values[0].stacktrace.frames;
4561
4424
  }
4562
- return null;
4425
+ catch (e) {
4426
+ // ignore
4427
+ }
4428
+ return frames ? this._getLastValidUrl(frames) : null;
4563
4429
  }
4564
4430
  catch (oO) {
4565
- logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
4431
+ if (isDebugBuild()) {
4432
+ logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
4433
+ }
4566
4434
  return null;
4567
4435
  }
4568
4436
  }
@@ -4924,7 +4792,7 @@ var Sentry = (function (exports) {
4924
4792
  }
4925
4793
 
4926
4794
  /**
4927
- * Builds and Event from a Exception
4795
+ * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
4928
4796
  * @hidden
4929
4797
  */
4930
4798
  function eventFromException(options, exception, hint) {
@@ -4937,7 +4805,7 @@ var Sentry = (function (exports) {
4937
4805
  if (hint && hint.event_id) {
4938
4806
  event.event_id = hint.event_id;
4939
4807
  }
4940
- return SyncPromise.resolve(event);
4808
+ return resolvedSyncPromise(event);
4941
4809
  }
4942
4810
  /**
4943
4811
  * Builds and Event from a Message
@@ -4952,7 +4820,7 @@ var Sentry = (function (exports) {
4952
4820
  if (hint && hint.event_id) {
4953
4821
  event.event_id = hint.event_id;
4954
4822
  }
4955
- return SyncPromise.resolve(event);
4823
+ return resolvedSyncPromise(event);
4956
4824
  }
4957
4825
  /**
4958
4826
  * @hidden
@@ -4996,11 +4864,11 @@ var Sentry = (function (exports) {
4996
4864
  return event;
4997
4865
  }
4998
4866
  if (isPlainObject(exception) || isEvent(exception)) {
4999
- // If it is plain Object or Event, serialize it manually and extract options
5000
- // This will allow us to group events based on top-level keys
5001
- // which is much better than creating new group when any key/value change
4867
+ // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
4868
+ // it manually. This will allow us to group events based on top-level keys which is much better than creating a new
4869
+ // group on any key/value change.
5002
4870
  const objectException = exception;
5003
- event = eventFromPlainObject(objectException, syntheticException, options.rejection);
4871
+ event = eventFromPlainObject(objectException, syntheticException, options.isRejection);
5004
4872
  addExceptionMechanism(event, {
5005
4873
  synthetic: true,
5006
4874
  });
@@ -5080,7 +4948,6 @@ var Sentry = (function (exports) {
5080
4948
  * Safari: resource blocked by content blocker
5081
4949
  */
5082
4950
  function getNativeFetchImplementation() {
5083
- var _a, _b;
5084
4951
  if (cachedFetchImpl) {
5085
4952
  return cachedFetchImpl;
5086
4953
  }
@@ -5092,18 +4959,21 @@ var Sentry = (function (exports) {
5092
4959
  const document = global$3.document;
5093
4960
  let fetchImpl = global$3.fetch;
5094
4961
  // eslint-disable-next-line deprecation/deprecation
5095
- if (typeof ((_a = document) === null || _a === void 0 ? void 0 : _a.createElement) === `function`) {
4962
+ if (document && typeof document.createElement === `function`) {
5096
4963
  try {
5097
4964
  const sandbox = document.createElement('iframe');
5098
4965
  sandbox.hidden = true;
5099
4966
  document.head.appendChild(sandbox);
5100
- if ((_b = sandbox.contentWindow) === null || _b === void 0 ? void 0 : _b.fetch) {
5101
- fetchImpl = sandbox.contentWindow.fetch;
4967
+ const contentWindow = sandbox.contentWindow;
4968
+ if (contentWindow && contentWindow.fetch) {
4969
+ fetchImpl = contentWindow.fetch;
5102
4970
  }
5103
4971
  document.head.removeChild(sandbox);
5104
4972
  }
5105
4973
  catch (e) {
5106
- logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
4974
+ if (isDebugBuild()) {
4975
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
4976
+ }
5107
4977
  }
5108
4978
  }
5109
4979
  return (cachedFetchImpl = fetchImpl.bind(global$3));
@@ -5134,25 +5004,23 @@ var Sentry = (function (exports) {
5134
5004
  }
5135
5005
  }
5136
5006
 
5137
- const CATEGORY_MAPPING = {
5138
- event: 'error',
5139
- transaction: 'transaction',
5140
- session: 'session',
5141
- attachment: 'attachment',
5142
- };
5007
+ function requestTypeToCategory(ty) {
5008
+ const tyStr = ty;
5009
+ return tyStr === 'event' ? 'error' : tyStr;
5010
+ }
5143
5011
  const global$4 = getGlobalObject();
5144
5012
  /** Base Transport class implementation */
5145
5013
  class BaseTransport {
5146
5014
  constructor(options) {
5147
5015
  this.options = options;
5148
5016
  /** A simple buffer holding all requests. */
5149
- this._buffer = new PromiseBuffer(30);
5017
+ this._buffer = makePromiseBuffer(30);
5150
5018
  /** Locks transport after receiving rate limits in a response */
5151
5019
  this._rateLimits = {};
5152
5020
  this._outcomes = {};
5153
- this._api = new API(options.dsn, options._metadata, options.tunnel);
5021
+ this._api = initAPIDetails(options.dsn, options._metadata, options.tunnel);
5154
5022
  // eslint-disable-next-line deprecation/deprecation
5155
- this.url = this._api.getStoreEndpointWithUrlEncodedAuth();
5023
+ this.url = getStoreEndpointWithUrlEncodedAuth(this._api.dsn);
5156
5024
  if (this.options.sendClientReports && global$4.document) {
5157
5025
  global$4.document.addEventListener('visibilitychange', () => {
5158
5026
  if (global$4.document.visibilityState === 'hidden') {
@@ -5164,8 +5032,14 @@ var Sentry = (function (exports) {
5164
5032
  /**
5165
5033
  * @inheritDoc
5166
5034
  */
5167
- sendEvent(_) {
5168
- throw new SentryError('Transport Class has to implement `sendEvent` method');
5035
+ sendEvent(event) {
5036
+ return this._sendRequest(eventToSentryRequest(event, this._api), event);
5037
+ }
5038
+ /**
5039
+ * @inheritDoc
5040
+ */
5041
+ sendSession(session) {
5042
+ return this._sendRequest(sessionToSentryRequest(session, this._api), session);
5169
5043
  }
5170
5044
  /**
5171
5045
  * @inheritDoc
@@ -5186,7 +5060,7 @@ var Sentry = (function (exports) {
5186
5060
  // We could use nested maps, but it's much easier to read and type this way.
5187
5061
  // A correct type for map-based implementation if we want to go that route
5188
5062
  // would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
5189
- const key = `${CATEGORY_MAPPING[category]}:${reason}`;
5063
+ const key = `${requestTypeToCategory(category)}:${reason}`;
5190
5064
  logger.log(`Adding outcome: ${key}`);
5191
5065
  this._outcomes[key] = (_a = this._outcomes[key], (_a !== null && _a !== void 0 ? _a : 0)) + 1;
5192
5066
  }
@@ -5205,9 +5079,9 @@ var Sentry = (function (exports) {
5205
5079
  return;
5206
5080
  }
5207
5081
  logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
5208
- const url = this._api.getEnvelopeEndpointWithUrlEncodedAuth();
5082
+ const url = getEnvelopeEndpointWithUrlEncodedAuth(this._api.dsn, this._api.tunnel);
5209
5083
  // Envelope header is required to be at least an empty object
5210
- const envelopeHeader = JSON.stringify(Object.assign({}, (this.options.tunnel && { dsn: this._api.getDsn().toString() })));
5084
+ const envelopeHeader = JSON.stringify(Object.assign({}, (this._api.tunnel && { dsn: dsnToString(this._api.dsn) })));
5211
5085
  const itemHeaders = JSON.stringify({
5212
5086
  type: 'client_report',
5213
5087
  });
@@ -5234,15 +5108,16 @@ var Sentry = (function (exports) {
5234
5108
  * Handle Sentry repsonse for promise-based transports.
5235
5109
  */
5236
5110
  _handleResponse({ requestType, response, headers, resolve, reject, }) {
5237
- const status = exports.Status.fromHttpCode(response.status);
5111
+ const status = eventStatusFromHttpCode(response.status);
5238
5112
  /**
5239
5113
  * "The name is case-insensitive."
5240
5114
  * https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
5241
5115
  */
5242
5116
  const limited = this._handleRateLimit(headers);
5243
- if (limited)
5117
+ if (limited && isDebugBuild()) {
5244
5118
  logger.warn(`Too many ${requestType} requests, backing off until: ${this._disabledUntil(requestType)}`);
5245
- if (status === exports.Status.Success) {
5119
+ }
5120
+ if (status === 'success') {
5246
5121
  resolve({ status });
5247
5122
  return;
5248
5123
  }
@@ -5252,7 +5127,7 @@ var Sentry = (function (exports) {
5252
5127
  * Gets the time that given category is disabled until for rate limiting
5253
5128
  */
5254
5129
  _disabledUntil(requestType) {
5255
- const category = CATEGORY_MAPPING[requestType];
5130
+ const category = requestTypeToCategory(requestType);
5256
5131
  return this._rateLimits[category] || this._rateLimits.all;
5257
5132
  }
5258
5133
  /**
@@ -5303,25 +5178,13 @@ var Sentry = (function (exports) {
5303
5178
  super(options);
5304
5179
  this._fetch = fetchImpl;
5305
5180
  }
5306
- /**
5307
- * @inheritDoc
5308
- */
5309
- sendEvent(event) {
5310
- return this._sendRequest(eventToSentryRequest(event, this._api), event);
5311
- }
5312
- /**
5313
- * @inheritDoc
5314
- */
5315
- sendSession(session) {
5316
- return this._sendRequest(sessionToSentryRequest(session, this._api), session);
5317
- }
5318
5181
  /**
5319
5182
  * @param sentryRequest Prepared SentryRequest to be delivered
5320
5183
  * @param originalPayload Original payload used to create SentryRequest
5321
5184
  */
5322
5185
  _sendRequest(sentryRequest, originalPayload) {
5323
5186
  if (this._isRateLimited(sentryRequest.type)) {
5324
- this.recordLostEvent(Outcome.RateLimitBackoff, sentryRequest.type);
5187
+ this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
5325
5188
  return Promise.reject({
5326
5189
  event: originalPayload,
5327
5190
  type: sentryRequest.type,
@@ -5332,9 +5195,9 @@ var Sentry = (function (exports) {
5332
5195
  const options = {
5333
5196
  body: sentryRequest.body,
5334
5197
  method: 'POST',
5335
- // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
5336
- // https://caniuse.com/#feat=referrer-policy
5337
- // It doesn't. And it throw exception instead of ignoring this parameter...
5198
+ // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
5199
+ // (see https://caniuse.com/#feat=referrer-policy),
5200
+ // it doesn't. And it throws an exception instead of ignoring this parameter...
5338
5201
  // REF: https://github.com/getsentry/raven-js/issues/1233
5339
5202
  referrerPolicy: (supportsReferrerPolicy() ? 'origin' : ''),
5340
5203
  };
@@ -5365,10 +5228,10 @@ var Sentry = (function (exports) {
5365
5228
  .then(undefined, reason => {
5366
5229
  // It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
5367
5230
  if (reason instanceof SentryError) {
5368
- this.recordLostEvent(Outcome.QueueOverflow, sentryRequest.type);
5231
+ this.recordLostEvent('queue_overflow', sentryRequest.type);
5369
5232
  }
5370
5233
  else {
5371
- this.recordLostEvent(Outcome.NetworkError, sentryRequest.type);
5234
+ this.recordLostEvent('network_error', sentryRequest.type);
5372
5235
  }
5373
5236
  throw reason;
5374
5237
  });
@@ -5377,25 +5240,13 @@ var Sentry = (function (exports) {
5377
5240
 
5378
5241
  /** `XHR` based transport */
5379
5242
  class XHRTransport extends BaseTransport {
5380
- /**
5381
- * @inheritDoc
5382
- */
5383
- sendEvent(event) {
5384
- return this._sendRequest(eventToSentryRequest(event, this._api), event);
5385
- }
5386
- /**
5387
- * @inheritDoc
5388
- */
5389
- sendSession(session) {
5390
- return this._sendRequest(sessionToSentryRequest(session, this._api), session);
5391
- }
5392
5243
  /**
5393
5244
  * @param sentryRequest Prepared SentryRequest to be delivered
5394
5245
  * @param originalPayload Original payload used to create SentryRequest
5395
5246
  */
5396
5247
  _sendRequest(sentryRequest, originalPayload) {
5397
5248
  if (this._isRateLimited(sentryRequest.type)) {
5398
- this.recordLostEvent(Outcome.RateLimitBackoff, sentryRequest.type);
5249
+ this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
5399
5250
  return Promise.reject({
5400
5251
  event: originalPayload,
5401
5252
  type: sentryRequest.type,
@@ -5426,10 +5277,10 @@ var Sentry = (function (exports) {
5426
5277
  .then(undefined, reason => {
5427
5278
  // It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
5428
5279
  if (reason instanceof SentryError) {
5429
- this.recordLostEvent(Outcome.QueueOverflow, sentryRequest.type);
5280
+ this.recordLostEvent('queue_overflow', sentryRequest.type);
5430
5281
  }
5431
5282
  else {
5432
- this.recordLostEvent(Outcome.NetworkError, sentryRequest.type);
5283
+ this.recordLostEvent('network_error', sentryRequest.type);
5433
5284
  }
5434
5285
  throw reason;
5435
5286
  });
@@ -5508,18 +5359,26 @@ var Sentry = (function (exports) {
5508
5359
  * @hidden
5509
5360
  */
5510
5361
  function wrap(fn, options = {}, before) {
5362
+ // for future readers what this does is wrap a function and then create
5363
+ // a bi-directional wrapping between them.
5364
+ //
5365
+ // example: wrapped = wrap(original);
5366
+ // original.__sentry_wrapped__ -> wrapped
5367
+ // wrapped.__sentry_original__ -> original
5511
5368
  if (typeof fn !== 'function') {
5512
5369
  return fn;
5513
5370
  }
5514
5371
  try {
5372
+ // if we're dealing with a function that was previously wrapped, return
5373
+ // the original wrapper.
5374
+ const wrapper = fn.__sentry_wrapped__;
5375
+ if (wrapper) {
5376
+ return wrapper;
5377
+ }
5515
5378
  // We don't wanna wrap it twice
5516
- if (fn.__sentry__) {
5379
+ if (getOriginalFunction(fn)) {
5517
5380
  return fn;
5518
5381
  }
5519
- // If this has already been wrapped in the past, return that wrapped function
5520
- if (fn.__sentry_wrapped__) {
5521
- return fn.__sentry_wrapped__;
5522
- }
5523
5382
  }
5524
5383
  catch (e) {
5525
5384
  // Just accessing custom props in some Selenium environments
@@ -5537,14 +5396,6 @@ var Sentry = (function (exports) {
5537
5396
  }
5538
5397
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
5539
5398
  const wrappedArguments = args.map((arg) => wrap(arg, options));
5540
- if (fn.handleEvent) {
5541
- // Attempt to invoke user-land function
5542
- // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
5543
- // means the sentry.javascript SDK caught an error invoking your application code. This
5544
- // is expected behavior and NOT indicative of a bug with sentry.javascript.
5545
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5546
- return fn.handleEvent.apply(this, wrappedArguments);
5547
- }
5548
5399
  // Attempt to invoke user-land function
5549
5400
  // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
5550
5401
  // means the sentry.javascript SDK caught an error invoking your application code. This
@@ -5555,13 +5406,12 @@ var Sentry = (function (exports) {
5555
5406
  ignoreNextOnError();
5556
5407
  withScope((scope) => {
5557
5408
  scope.addEventProcessor((event) => {
5558
- const processedEvent = Object.assign({}, event);
5559
5409
  if (options.mechanism) {
5560
- addExceptionTypeValue(processedEvent, undefined, undefined);
5561
- addExceptionMechanism(processedEvent, options.mechanism);
5410
+ addExceptionTypeValue(event, undefined, undefined);
5411
+ addExceptionMechanism(event, options.mechanism);
5562
5412
  }
5563
- processedEvent.extra = Object.assign(Object.assign({}, processedEvent.extra), { arguments: args });
5564
- return processedEvent;
5413
+ event.extra = Object.assign(Object.assign({}, event.extra), { arguments: args });
5414
+ return event;
5565
5415
  });
5566
5416
  captureException(ex);
5567
5417
  });
@@ -5579,24 +5429,10 @@ var Sentry = (function (exports) {
5579
5429
  }
5580
5430
  }
5581
5431
  catch (_oO) { } // eslint-disable-line no-empty
5582
- fn.prototype = fn.prototype || {};
5583
- sentryWrapped.prototype = fn.prototype;
5584
- Object.defineProperty(fn, '__sentry_wrapped__', {
5585
- enumerable: false,
5586
- value: sentryWrapped,
5587
- });
5588
5432
  // Signal that this function has been wrapped/filled already
5589
5433
  // for both debugging and to prevent it to being wrapped/filled twice
5590
- Object.defineProperties(sentryWrapped, {
5591
- __sentry__: {
5592
- enumerable: false,
5593
- value: true,
5594
- },
5595
- __sentry_original__: {
5596
- enumerable: false,
5597
- value: fn,
5598
- },
5599
- });
5434
+ markFunctionWrapped(sentryWrapped, fn);
5435
+ addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);
5600
5436
  // Restore original function name (not all browsers allow that)
5601
5437
  try {
5602
5438
  const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name');
@@ -5621,16 +5457,20 @@ var Sentry = (function (exports) {
5621
5457
  return;
5622
5458
  }
5623
5459
  if (!options.eventId) {
5624
- logger.error(`Missing eventId option in showReportDialog call`);
5460
+ if (isDebugBuild()) {
5461
+ logger.error(`Missing eventId option in showReportDialog call`);
5462
+ }
5625
5463
  return;
5626
5464
  }
5627
5465
  if (!options.dsn) {
5628
- logger.error(`Missing dsn option in showReportDialog call`);
5466
+ if (isDebugBuild()) {
5467
+ logger.error(`Missing dsn option in showReportDialog call`);
5468
+ }
5629
5469
  return;
5630
5470
  }
5631
5471
  const script = global$5.document.createElement('script');
5632
5472
  script.async = true;
5633
- script.src = new API(options.dsn).getReportDialogEndpoint(options);
5473
+ script.src = getReportDialogEndpoint(options.dsn, options);
5634
5474
  if (options.onLoad) {
5635
5475
  // eslint-disable-next-line @typescript-eslint/unbound-method
5636
5476
  script.onload = options.onLoad;
@@ -5650,10 +5490,14 @@ var Sentry = (function (exports) {
5650
5490
  * @inheritDoc
5651
5491
  */
5652
5492
  this.name = GlobalHandlers.id;
5653
- /** JSDoc */
5654
- this._onErrorHandlerInstalled = false;
5655
- /** JSDoc */
5656
- this._onUnhandledRejectionHandlerInstalled = false;
5493
+ /**
5494
+ * Stores references functions to installing handlers. Will set to undefined
5495
+ * after they have been run so that they are not used twice.
5496
+ */
5497
+ this._installFunc = {
5498
+ onerror: _installGlobalOnErrorHandler,
5499
+ onunhandledrejection: _installGlobalOnUnhandledRejectionHandler,
5500
+ };
5657
5501
  this._options = Object.assign({ onerror: true, onunhandledrejection: true }, options);
5658
5502
  }
5659
5503
  /**
@@ -5661,176 +5505,182 @@ var Sentry = (function (exports) {
5661
5505
  */
5662
5506
  setupOnce() {
5663
5507
  Error.stackTraceLimit = 50;
5664
- if (this._options.onerror) {
5665
- logger.log('Global Handler attached: onerror');
5666
- this._installGlobalOnErrorHandler();
5667
- }
5668
- if (this._options.onunhandledrejection) {
5669
- logger.log('Global Handler attached: onunhandledrejection');
5670
- this._installGlobalOnUnhandledRejectionHandler();
5508
+ const options = this._options;
5509
+ // We can disable guard-for-in as we construct the options object above + do checks against
5510
+ // `this._installFunc` for the property.
5511
+ // eslint-disable-next-line guard-for-in
5512
+ for (const key in options) {
5513
+ const installFunc = this._installFunc[key];
5514
+ if (installFunc && options[key]) {
5515
+ globalHandlerLog(key);
5516
+ installFunc();
5517
+ this._installFunc[key] = undefined;
5518
+ }
5671
5519
  }
5672
5520
  }
5673
- /** JSDoc */
5674
- _installGlobalOnErrorHandler() {
5675
- if (this._onErrorHandlerInstalled) {
5521
+ }
5522
+ /**
5523
+ * @inheritDoc
5524
+ */
5525
+ GlobalHandlers.id = 'GlobalHandlers';
5526
+ /** JSDoc */
5527
+ function _installGlobalOnErrorHandler() {
5528
+ addInstrumentationHandler('error',
5529
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5530
+ (data) => {
5531
+ const [hub, attachStacktrace] = getHubAndAttachStacktrace();
5532
+ if (!hub.getIntegration(GlobalHandlers)) {
5676
5533
  return;
5677
5534
  }
5678
- addInstrumentationHandler({
5679
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5680
- callback: (data) => {
5681
- const error = data.error;
5682
- const currentHub = getCurrentHub();
5683
- const hasIntegration = currentHub.getIntegration(GlobalHandlers);
5684
- const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
5685
- if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
5686
- return;
5687
- }
5688
- const client = currentHub.getClient();
5689
- const event = error === undefined && isString(data.msg)
5690
- ? this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
5691
- : this._enhanceEventWithInitialFrame(eventFromUnknownInput(error || data.msg, undefined, {
5692
- attachStacktrace: client && client.getOptions().attachStacktrace,
5693
- rejection: false,
5694
- }), data.url, data.line, data.column);
5695
- addExceptionMechanism(event, {
5696
- handled: false,
5697
- type: 'onerror',
5698
- });
5699
- currentHub.captureEvent(event, {
5700
- originalException: error,
5701
- });
5702
- },
5703
- type: 'error',
5704
- });
5705
- this._onErrorHandlerInstalled = true;
5706
- }
5707
- /** JSDoc */
5708
- _installGlobalOnUnhandledRejectionHandler() {
5709
- if (this._onUnhandledRejectionHandlerInstalled) {
5535
+ const { msg, url, line, column, error } = data;
5536
+ if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
5710
5537
  return;
5711
5538
  }
5712
- addInstrumentationHandler({
5713
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5714
- callback: (e) => {
5715
- let error = e;
5716
- // dig the object of the rejection out of known event types
5717
- try {
5718
- // PromiseRejectionEvents store the object of the rejection under 'reason'
5719
- // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
5720
- if ('reason' in e) {
5721
- error = e.reason;
5722
- }
5723
- // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
5724
- // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
5725
- // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
5726
- // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
5727
- // https://github.com/getsentry/sentry-javascript/issues/2380
5728
- else if ('detail' in e && 'reason' in e.detail) {
5729
- error = e.detail.reason;
5730
- }
5731
- }
5732
- catch (_oO) {
5733
- // no-empty
5734
- }
5735
- const currentHub = getCurrentHub();
5736
- const hasIntegration = currentHub.getIntegration(GlobalHandlers);
5737
- const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
5738
- if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
5739
- return true;
5740
- }
5741
- const client = currentHub.getClient();
5742
- const event = isPrimitive(error)
5743
- ? this._eventFromRejectionWithPrimitive(error)
5744
- : eventFromUnknownInput(error, undefined, {
5745
- attachStacktrace: client && client.getOptions().attachStacktrace,
5746
- rejection: true,
5747
- });
5748
- event.level = exports.Severity.Error;
5749
- addExceptionMechanism(event, {
5750
- handled: false,
5751
- type: 'onunhandledrejection',
5752
- });
5753
- currentHub.captureEvent(event, {
5754
- originalException: error,
5755
- });
5756
- return;
5757
- },
5758
- type: 'unhandledrejection',
5759
- });
5760
- this._onUnhandledRejectionHandlerInstalled = true;
5761
- }
5762
- /**
5763
- * This function creates a stack from an old, error-less onerror handler.
5764
- */
5765
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5766
- _eventFromIncompleteOnError(msg, url, line, column) {
5767
- const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
5768
- // If 'message' is ErrorEvent, get real message from inside
5769
- let message = isErrorEvent(msg) ? msg.message : msg;
5770
- let name;
5771
- const groups = message.match(ERROR_TYPES_RE);
5772
- if (groups) {
5773
- name = groups[1];
5774
- message = groups[2];
5775
- }
5776
- const event = {
5777
- exception: {
5778
- values: [
5779
- {
5780
- type: name || 'Error',
5781
- value: message,
5782
- },
5783
- ],
5784
- },
5785
- };
5786
- return this._enhanceEventWithInitialFrame(event, url, line, column);
5787
- }
5788
- /**
5789
- * Create an event from a promise rejection where the `reason` is a primitive.
5790
- *
5791
- * @param reason: The `reason` property of the promise rejection
5792
- * @returns An Event object with an appropriate `exception` value
5793
- */
5794
- _eventFromRejectionWithPrimitive(reason) {
5795
- return {
5796
- exception: {
5797
- values: [
5798
- {
5799
- type: 'UnhandledRejection',
5800
- // String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
5801
- value: `Non-Error promise rejection captured with value: ${String(reason)}`,
5802
- },
5803
- ],
5804
- },
5805
- };
5806
- }
5807
- /** JSDoc */
5539
+ const event = error === undefined && isString(msg)
5540
+ ? _eventFromIncompleteOnError(msg, url, line, column)
5541
+ : _enhanceEventWithInitialFrame(eventFromUnknownInput(error || msg, undefined, {
5542
+ attachStacktrace,
5543
+ isRejection: false,
5544
+ }), url, line, column);
5545
+ addMechanismAndCapture(hub, error, event, 'onerror');
5546
+ });
5547
+ }
5548
+ /** JSDoc */
5549
+ function _installGlobalOnUnhandledRejectionHandler() {
5550
+ addInstrumentationHandler('unhandledrejection',
5808
5551
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5809
- _enhanceEventWithInitialFrame(event, url, line, column) {
5810
- event.exception = event.exception || {};
5811
- event.exception.values = event.exception.values || [];
5812
- event.exception.values[0] = event.exception.values[0] || {};
5813
- event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {};
5814
- event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || [];
5815
- const colno = isNaN(parseInt(column, 10)) ? undefined : column;
5816
- const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
5817
- const filename = isString(url) && url.length > 0 ? url : getLocationHref();
5818
- if (event.exception.values[0].stacktrace.frames.length === 0) {
5819
- event.exception.values[0].stacktrace.frames.push({
5820
- colno,
5821
- filename,
5822
- function: '?',
5823
- in_app: true,
5824
- lineno,
5825
- });
5552
+ (e) => {
5553
+ const [hub, attachStacktrace] = getHubAndAttachStacktrace();
5554
+ if (!hub.getIntegration(GlobalHandlers)) {
5555
+ return;
5826
5556
  }
5827
- return event;
5828
- }
5557
+ let error = e;
5558
+ // dig the object of the rejection out of known event types
5559
+ try {
5560
+ // PromiseRejectionEvents store the object of the rejection under 'reason'
5561
+ // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
5562
+ if ('reason' in e) {
5563
+ error = e.reason;
5564
+ }
5565
+ // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
5566
+ // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
5567
+ // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
5568
+ // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
5569
+ // https://github.com/getsentry/sentry-javascript/issues/2380
5570
+ else if ('detail' in e && 'reason' in e.detail) {
5571
+ error = e.detail.reason;
5572
+ }
5573
+ }
5574
+ catch (_oO) {
5575
+ // no-empty
5576
+ }
5577
+ if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
5578
+ return true;
5579
+ }
5580
+ const event = isPrimitive(error)
5581
+ ? _eventFromRejectionWithPrimitive(error)
5582
+ : eventFromUnknownInput(error, undefined, {
5583
+ attachStacktrace,
5584
+ isRejection: true,
5585
+ });
5586
+ event.level = exports.Severity.Error;
5587
+ addMechanismAndCapture(hub, error, event, 'onunhandledrejection');
5588
+ return;
5589
+ });
5829
5590
  }
5830
5591
  /**
5831
- * @inheritDoc
5592
+ * Create an event from a promise rejection where the `reason` is a primitive.
5593
+ *
5594
+ * @param reason: The `reason` property of the promise rejection
5595
+ * @returns An Event object with an appropriate `exception` value
5596
+ */
5597
+ function _eventFromRejectionWithPrimitive(reason) {
5598
+ return {
5599
+ exception: {
5600
+ values: [
5601
+ {
5602
+ type: 'UnhandledRejection',
5603
+ // String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
5604
+ value: `Non-Error promise rejection captured with value: ${String(reason)}`,
5605
+ },
5606
+ ],
5607
+ },
5608
+ };
5609
+ }
5610
+ /**
5611
+ * This function creates a stack from an old, error-less onerror handler.
5832
5612
  */
5833
- GlobalHandlers.id = 'GlobalHandlers';
5613
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5614
+ function _eventFromIncompleteOnError(msg, url, line, column) {
5615
+ const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
5616
+ // If 'message' is ErrorEvent, get real message from inside
5617
+ let message = isErrorEvent(msg) ? msg.message : msg;
5618
+ let name = 'Error';
5619
+ const groups = message.match(ERROR_TYPES_RE);
5620
+ if (groups) {
5621
+ name = groups[1];
5622
+ message = groups[2];
5623
+ }
5624
+ const event = {
5625
+ exception: {
5626
+ values: [
5627
+ {
5628
+ type: name,
5629
+ value: message,
5630
+ },
5631
+ ],
5632
+ },
5633
+ };
5634
+ return _enhanceEventWithInitialFrame(event, url, line, column);
5635
+ }
5636
+ /** JSDoc */
5637
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5638
+ function _enhanceEventWithInitialFrame(event, url, line, column) {
5639
+ // event.exception
5640
+ const e = (event.exception = event.exception || {});
5641
+ // event.exception.values
5642
+ const ev = (e.values = e.values || []);
5643
+ // event.exception.values[0]
5644
+ const ev0 = (ev[0] = ev[0] || {});
5645
+ // event.exception.values[0].stacktrace
5646
+ const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
5647
+ // event.exception.values[0].stacktrace.frames
5648
+ const ev0sf = (ev0s.frames = ev0s.frames || []);
5649
+ const colno = isNaN(parseInt(column, 10)) ? undefined : column;
5650
+ const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
5651
+ const filename = isString(url) && url.length > 0 ? url : getLocationHref();
5652
+ // event.exception.values[0].stacktrace.frames
5653
+ if (ev0sf.length === 0) {
5654
+ ev0sf.push({
5655
+ colno,
5656
+ filename,
5657
+ function: '?',
5658
+ in_app: true,
5659
+ lineno,
5660
+ });
5661
+ }
5662
+ return event;
5663
+ }
5664
+ function globalHandlerLog(type) {
5665
+ if (isDebugBuild()) {
5666
+ logger.log(`Global Handler attached: ${type}`);
5667
+ }
5668
+ }
5669
+ function addMechanismAndCapture(hub, error, event, type) {
5670
+ addExceptionMechanism(event, {
5671
+ handled: false,
5672
+ type,
5673
+ });
5674
+ hub.captureEvent(event, {
5675
+ originalException: error,
5676
+ });
5677
+ }
5678
+ function getHubAndAttachStacktrace() {
5679
+ const hub = getCurrentHub();
5680
+ const client = hub.getClient();
5681
+ const attachStacktrace = client && client.getOptions().attachStacktrace;
5682
+ return [hub, attachStacktrace];
5683
+ }
5834
5684
 
5835
5685
  const DEFAULT_EVENT_TARGET = [
5836
5686
  'EventTarget',
@@ -5882,172 +5732,173 @@ var Sentry = (function (exports) {
5882
5732
  setupOnce() {
5883
5733
  const global = getGlobalObject();
5884
5734
  if (this._options.setTimeout) {
5885
- fill(global, 'setTimeout', this._wrapTimeFunction.bind(this));
5735
+ fill(global, 'setTimeout', _wrapTimeFunction);
5886
5736
  }
5887
5737
  if (this._options.setInterval) {
5888
- fill(global, 'setInterval', this._wrapTimeFunction.bind(this));
5738
+ fill(global, 'setInterval', _wrapTimeFunction);
5889
5739
  }
5890
5740
  if (this._options.requestAnimationFrame) {
5891
- fill(global, 'requestAnimationFrame', this._wrapRAF.bind(this));
5741
+ fill(global, 'requestAnimationFrame', _wrapRAF);
5892
5742
  }
5893
5743
  if (this._options.XMLHttpRequest && 'XMLHttpRequest' in global) {
5894
- fill(XMLHttpRequest.prototype, 'send', this._wrapXHR.bind(this));
5744
+ fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
5895
5745
  }
5896
- if (this._options.eventTarget) {
5897
- const eventTarget = Array.isArray(this._options.eventTarget) ? this._options.eventTarget : DEFAULT_EVENT_TARGET;
5898
- eventTarget.forEach(this._wrapEventTarget.bind(this));
5746
+ const eventTargetOption = this._options.eventTarget;
5747
+ if (eventTargetOption) {
5748
+ const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
5749
+ eventTarget.forEach(_wrapEventTarget);
5899
5750
  }
5900
5751
  }
5901
- /** JSDoc */
5902
- _wrapTimeFunction(original) {
5903
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5904
- return function (...args) {
5905
- const originalCallback = args[0];
5906
- args[0] = wrap(originalCallback, {
5907
- mechanism: {
5908
- data: { function: getFunctionName(original) },
5909
- handled: true,
5910
- type: 'instrument',
5911
- },
5912
- });
5913
- return original.apply(this, args);
5914
- };
5915
- }
5916
- /** JSDoc */
5752
+ }
5753
+ /**
5754
+ * @inheritDoc
5755
+ */
5756
+ TryCatch.id = 'TryCatch';
5757
+ /** JSDoc */
5758
+ function _wrapTimeFunction(original) {
5917
5759
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5918
- _wrapRAF(original) {
5919
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5920
- return function (callback) {
5921
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5922
- return original.call(this, wrap(callback, {
5923
- mechanism: {
5924
- data: {
5925
- function: 'requestAnimationFrame',
5926
- handler: getFunctionName(original),
5927
- },
5928
- handled: true,
5929
- type: 'instrument',
5930
- },
5931
- }));
5932
- };
5933
- }
5934
- /** JSDoc */
5935
- _wrapEventTarget(target) {
5936
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5937
- const global = getGlobalObject();
5760
+ return function (...args) {
5761
+ const originalCallback = args[0];
5762
+ args[0] = wrap(originalCallback, {
5763
+ mechanism: {
5764
+ data: { function: getFunctionName(original) },
5765
+ handled: true,
5766
+ type: 'instrument',
5767
+ },
5768
+ });
5769
+ return original.apply(this, args);
5770
+ };
5771
+ }
5772
+ /** JSDoc */
5773
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5774
+ function _wrapRAF(original) {
5775
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5776
+ return function (callback) {
5938
5777
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5939
- const proto = global[target] && global[target].prototype;
5940
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
5941
- if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
5942
- return;
5943
- }
5944
- fill(proto, 'addEventListener', function (original) {
5945
- return function (eventName, fn, options) {
5946
- try {
5947
- if (typeof fn.handleEvent === 'function') {
5948
- fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
5949
- mechanism: {
5950
- data: {
5951
- function: 'handleEvent',
5952
- handler: getFunctionName(fn),
5953
- target,
5954
- },
5955
- handled: true,
5956
- type: 'instrument',
5957
- },
5958
- });
5959
- }
5960
- }
5961
- catch (err) {
5962
- // can sometimes get 'Permission denied to access property "handle Event'
5963
- }
5964
- return original.call(this, eventName,
5778
+ return original.call(this, wrap(callback, {
5779
+ mechanism: {
5780
+ data: {
5781
+ function: 'requestAnimationFrame',
5782
+ handler: getFunctionName(original),
5783
+ },
5784
+ handled: true,
5785
+ type: 'instrument',
5786
+ },
5787
+ }));
5788
+ };
5789
+ }
5790
+ /** JSDoc */
5791
+ function _wrapXHR(originalSend) {
5792
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5793
+ return function (...args) {
5794
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
5795
+ const xhr = this;
5796
+ const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
5797
+ xmlHttpRequestProps.forEach(prop => {
5798
+ if (prop in xhr && typeof xhr[prop] === 'function') {
5965
5799
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5966
- wrap(fn, {
5967
- mechanism: {
5968
- data: {
5969
- function: 'addEventListener',
5970
- handler: getFunctionName(fn),
5971
- target,
5800
+ fill(xhr, prop, function (original) {
5801
+ const wrapOptions = {
5802
+ mechanism: {
5803
+ data: {
5804
+ function: prop,
5805
+ handler: getFunctionName(original),
5806
+ },
5807
+ handled: true,
5808
+ type: 'instrument',
5972
5809
  },
5973
- handled: true,
5974
- type: 'instrument',
5975
- },
5976
- }), options);
5977
- };
5978
- });
5979
- fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
5980
- return function (eventName, fn, options) {
5981
- var _a;
5982
- /**
5983
- * There are 2 possible scenarios here:
5984
- *
5985
- * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
5986
- * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
5987
- * as a pass-through, and call original `removeEventListener` with it.
5988
- *
5989
- * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
5990
- * our wrapped version of `addEventListener`, which internally calls `wrap` helper.
5991
- * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
5992
- * in order for us to make a distinction between wrapped/non-wrapped functions possible.
5993
- * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
5994
- *
5995
- * When someone adds a handler prior to initialization, and then do it again, but after,
5996
- * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
5997
- * to get rid of the initial handler and it'd stick there forever.
5998
- */
5999
- const wrappedEventHandler = fn;
6000
- try {
6001
- const originalEventHandler = (_a = wrappedEventHandler) === null || _a === void 0 ? void 0 : _a.__sentry_wrapped__;
6002
- if (originalEventHandler) {
6003
- originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
5810
+ };
5811
+ // If Instrument integration has been called before TryCatch, get the name of original function
5812
+ const originalFunction = getOriginalFunction(original);
5813
+ if (originalFunction) {
5814
+ wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);
6004
5815
  }
6005
- }
6006
- catch (e) {
6007
- // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
6008
- }
6009
- return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
6010
- };
5816
+ // Otherwise wrap directly
5817
+ return wrap(original, wrapOptions);
5818
+ });
5819
+ }
6011
5820
  });
5821
+ return originalSend.apply(this, args);
5822
+ };
5823
+ }
5824
+ /** JSDoc */
5825
+ function _wrapEventTarget(target) {
5826
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5827
+ const global = getGlobalObject();
5828
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5829
+ const proto = global[target] && global[target].prototype;
5830
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
5831
+ if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
5832
+ return;
6012
5833
  }
6013
- /** JSDoc */
6014
- _wrapXHR(originalSend) {
6015
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6016
- return function (...args) {
6017
- // eslint-disable-next-line @typescript-eslint/no-this-alias
6018
- const xhr = this;
6019
- const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
6020
- xmlHttpRequestProps.forEach(prop => {
6021
- if (prop in xhr && typeof xhr[prop] === 'function') {
6022
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6023
- fill(xhr, prop, function (original) {
6024
- const wrapOptions = {
6025
- mechanism: {
6026
- data: {
6027
- function: prop,
6028
- handler: getFunctionName(original),
6029
- },
6030
- handled: true,
6031
- type: 'instrument',
5834
+ fill(proto, 'addEventListener', function (original) {
5835
+ return function (eventName, fn, options) {
5836
+ try {
5837
+ if (typeof fn.handleEvent === 'function') {
5838
+ fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
5839
+ mechanism: {
5840
+ data: {
5841
+ function: 'handleEvent',
5842
+ handler: getFunctionName(fn),
5843
+ target,
6032
5844
  },
6033
- };
6034
- // If Instrument integration has been called before TryCatch, get the name of original function
6035
- if (original.__sentry_original__) {
6036
- wrapOptions.mechanism.data.handler = getFunctionName(original.__sentry_original__);
6037
- }
6038
- // Otherwise wrap directly
6039
- return wrap(original, wrapOptions);
5845
+ handled: true,
5846
+ type: 'instrument',
5847
+ },
6040
5848
  });
6041
5849
  }
6042
- });
6043
- return originalSend.apply(this, args);
5850
+ }
5851
+ catch (err) {
5852
+ // can sometimes get 'Permission denied to access property "handle Event'
5853
+ }
5854
+ return original.call(this, eventName,
5855
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5856
+ wrap(fn, {
5857
+ mechanism: {
5858
+ data: {
5859
+ function: 'addEventListener',
5860
+ handler: getFunctionName(fn),
5861
+ target,
5862
+ },
5863
+ handled: true,
5864
+ type: 'instrument',
5865
+ },
5866
+ }), options);
6044
5867
  };
6045
- }
6046
- }
6047
- /**
6048
- * @inheritDoc
6049
- */
6050
- TryCatch.id = 'TryCatch';
5868
+ });
5869
+ fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
5870
+ return function (eventName, fn, options) {
5871
+ /**
5872
+ * There are 2 possible scenarios here:
5873
+ *
5874
+ * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
5875
+ * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
5876
+ * as a pass-through, and call original `removeEventListener` with it.
5877
+ *
5878
+ * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
5879
+ * our wrapped version of `addEventListener`, which internally calls `wrap` helper.
5880
+ * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
5881
+ * in order for us to make a distinction between wrapped/non-wrapped functions possible.
5882
+ * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
5883
+ *
5884
+ * When someone adds a handler prior to initialization, and then do it again, but after,
5885
+ * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
5886
+ * to get rid of the initial handler and it'd stick there forever.
5887
+ */
5888
+ const wrappedEventHandler = fn;
5889
+ try {
5890
+ const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
5891
+ if (originalEventHandler) {
5892
+ originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
5893
+ }
5894
+ }
5895
+ catch (e) {
5896
+ // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
5897
+ }
5898
+ return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
5899
+ };
5900
+ });
5901
+ }
6051
5902
 
6052
5903
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
6053
5904
  /**
@@ -6091,82 +5942,36 @@ var Sentry = (function (exports) {
6091
5942
  */
6092
5943
  setupOnce() {
6093
5944
  if (this._options.console) {
6094
- addInstrumentationHandler({
6095
- callback: (...args) => {
6096
- this._consoleBreadcrumb(...args);
6097
- },
6098
- type: 'console',
6099
- });
5945
+ addInstrumentationHandler('console', _consoleBreadcrumb);
6100
5946
  }
6101
5947
  if (this._options.dom) {
6102
- addInstrumentationHandler({
6103
- callback: (...args) => {
6104
- this._domBreadcrumb(...args);
6105
- },
6106
- type: 'dom',
6107
- });
5948
+ addInstrumentationHandler('dom', _domBreadcrumb(this._options.dom));
6108
5949
  }
6109
5950
  if (this._options.xhr) {
6110
- addInstrumentationHandler({
6111
- callback: (...args) => {
6112
- this._xhrBreadcrumb(...args);
6113
- },
6114
- type: 'xhr',
6115
- });
5951
+ addInstrumentationHandler('xhr', _xhrBreadcrumb);
6116
5952
  }
6117
5953
  if (this._options.fetch) {
6118
- addInstrumentationHandler({
6119
- callback: (...args) => {
6120
- this._fetchBreadcrumb(...args);
6121
- },
6122
- type: 'fetch',
6123
- });
5954
+ addInstrumentationHandler('fetch', _fetchBreadcrumb);
6124
5955
  }
6125
5956
  if (this._options.history) {
6126
- addInstrumentationHandler({
6127
- callback: (...args) => {
6128
- this._historyBreadcrumb(...args);
6129
- },
6130
- type: 'history',
6131
- });
6132
- }
6133
- }
6134
- /**
6135
- * Creates breadcrumbs from console API calls
6136
- */
6137
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6138
- _consoleBreadcrumb(handlerData) {
6139
- const breadcrumb = {
6140
- category: 'console',
6141
- data: {
6142
- arguments: handlerData.args,
6143
- logger: 'console',
6144
- },
6145
- level: exports.Severity.fromString(handlerData.level),
6146
- message: safeJoin(handlerData.args, ' '),
6147
- };
6148
- if (handlerData.level === 'assert') {
6149
- if (handlerData.args[0] === false) {
6150
- breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
6151
- breadcrumb.data.arguments = handlerData.args.slice(1);
6152
- }
6153
- else {
6154
- // Don't capture a breadcrumb for passed assertions
6155
- return;
6156
- }
5957
+ addInstrumentationHandler('history', _historyBreadcrumb);
6157
5958
  }
6158
- getCurrentHub().addBreadcrumb(breadcrumb, {
6159
- input: handlerData.args,
6160
- level: handlerData.level,
6161
- });
6162
5959
  }
6163
- /**
6164
- * Creates breadcrumbs from DOM API calls
6165
- */
5960
+ }
5961
+ /**
5962
+ * @inheritDoc
5963
+ */
5964
+ Breadcrumbs.id = 'Breadcrumbs';
5965
+ /**
5966
+ * A HOC that creaes a function that creates breadcrumbs from DOM API calls.
5967
+ * This is a HOC so that we get access to dom options in the closure.
5968
+ */
5969
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5970
+ function _domBreadcrumb(dom) {
6166
5971
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6167
- _domBreadcrumb(handlerData) {
5972
+ function _innerDomBreadcrumb(handlerData) {
6168
5973
  let target;
6169
- let keyAttrs = typeof this._options.dom === 'object' ? this._options.dom.serializeAttribute : undefined;
5974
+ let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
6170
5975
  if (typeof keyAttrs === 'string') {
6171
5976
  keyAttrs = [keyAttrs];
6172
5977
  }
@@ -6191,103 +5996,129 @@ var Sentry = (function (exports) {
6191
5996
  global: handlerData.global,
6192
5997
  });
6193
5998
  }
6194
- /**
6195
- * Creates breadcrumbs from XHR API calls
6196
- */
6197
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6198
- _xhrBreadcrumb(handlerData) {
6199
- if (handlerData.endTimestamp) {
6200
- // We only capture complete, non-sentry requests
6201
- if (handlerData.xhr.__sentry_own_request__) {
6202
- return;
6203
- }
6204
- const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {};
6205
- getCurrentHub().addBreadcrumb({
6206
- category: 'xhr',
6207
- data: {
6208
- method,
6209
- url,
6210
- status_code,
6211
- },
6212
- type: 'http',
6213
- }, {
6214
- xhr: handlerData.xhr,
6215
- input: body,
6216
- });
6217
- return;
6218
- }
6219
- }
6220
- /**
6221
- * Creates breadcrumbs from fetch API calls
6222
- */
6223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6224
- _fetchBreadcrumb(handlerData) {
6225
- // We only capture complete fetch requests
6226
- if (!handlerData.endTimestamp) {
6227
- return;
6228
- }
6229
- if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
6230
- // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
6231
- return;
6232
- }
6233
- if (handlerData.error) {
6234
- getCurrentHub().addBreadcrumb({
6235
- category: 'fetch',
6236
- data: handlerData.fetchData,
6237
- level: exports.Severity.Error,
6238
- type: 'http',
6239
- }, {
6240
- data: handlerData.error,
6241
- input: handlerData.args,
6242
- });
5999
+ return _innerDomBreadcrumb;
6000
+ }
6001
+ /**
6002
+ * Creates breadcrumbs from console API calls
6003
+ */
6004
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6005
+ function _consoleBreadcrumb(handlerData) {
6006
+ const breadcrumb = {
6007
+ category: 'console',
6008
+ data: {
6009
+ arguments: handlerData.args,
6010
+ logger: 'console',
6011
+ },
6012
+ level: severityFromString(handlerData.level),
6013
+ message: safeJoin(handlerData.args, ' '),
6014
+ };
6015
+ if (handlerData.level === 'assert') {
6016
+ if (handlerData.args[0] === false) {
6017
+ breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
6018
+ breadcrumb.data.arguments = handlerData.args.slice(1);
6243
6019
  }
6244
6020
  else {
6245
- getCurrentHub().addBreadcrumb({
6246
- category: 'fetch',
6247
- data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
6248
- type: 'http',
6249
- }, {
6250
- input: handlerData.args,
6251
- response: handlerData.response,
6252
- });
6021
+ // Don't capture a breadcrumb for passed assertions
6022
+ return;
6253
6023
  }
6254
6024
  }
6255
- /**
6256
- * Creates breadcrumbs from history API calls
6257
- */
6258
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6259
- _historyBreadcrumb(handlerData) {
6260
- const global = getGlobalObject();
6261
- let from = handlerData.from;
6262
- let to = handlerData.to;
6263
- const parsedLoc = parseUrl(global.location.href);
6264
- let parsedFrom = parseUrl(from);
6265
- const parsedTo = parseUrl(to);
6266
- // Initial pushState doesn't provide `from` information
6267
- if (!parsedFrom.path) {
6268
- parsedFrom = parsedLoc;
6269
- }
6270
- // Use only the path component of the URL if the URL matches the current
6271
- // document (almost all the time when using pushState)
6272
- if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
6273
- to = parsedTo.relative;
6274
- }
6275
- if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
6276
- from = parsedFrom.relative;
6025
+ getCurrentHub().addBreadcrumb(breadcrumb, {
6026
+ input: handlerData.args,
6027
+ level: handlerData.level,
6028
+ });
6029
+ }
6030
+ /**
6031
+ * Creates breadcrumbs from XHR API calls
6032
+ */
6033
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6034
+ function _xhrBreadcrumb(handlerData) {
6035
+ if (handlerData.endTimestamp) {
6036
+ // We only capture complete, non-sentry requests
6037
+ if (handlerData.xhr.__sentry_own_request__) {
6038
+ return;
6277
6039
  }
6040
+ const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {};
6278
6041
  getCurrentHub().addBreadcrumb({
6279
- category: 'navigation',
6042
+ category: 'xhr',
6280
6043
  data: {
6281
- from,
6282
- to,
6044
+ method,
6045
+ url,
6046
+ status_code,
6283
6047
  },
6048
+ type: 'http',
6049
+ }, {
6050
+ xhr: handlerData.xhr,
6051
+ input: body,
6284
6052
  });
6053
+ return;
6285
6054
  }
6286
6055
  }
6287
6056
  /**
6288
- * @inheritDoc
6057
+ * Creates breadcrumbs from fetch API calls
6289
6058
  */
6290
- Breadcrumbs.id = 'Breadcrumbs';
6059
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6060
+ function _fetchBreadcrumb(handlerData) {
6061
+ // We only capture complete fetch requests
6062
+ if (!handlerData.endTimestamp) {
6063
+ return;
6064
+ }
6065
+ if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
6066
+ // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
6067
+ return;
6068
+ }
6069
+ if (handlerData.error) {
6070
+ getCurrentHub().addBreadcrumb({
6071
+ category: 'fetch',
6072
+ data: handlerData.fetchData,
6073
+ level: exports.Severity.Error,
6074
+ type: 'http',
6075
+ }, {
6076
+ data: handlerData.error,
6077
+ input: handlerData.args,
6078
+ });
6079
+ }
6080
+ else {
6081
+ getCurrentHub().addBreadcrumb({
6082
+ category: 'fetch',
6083
+ data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
6084
+ type: 'http',
6085
+ }, {
6086
+ input: handlerData.args,
6087
+ response: handlerData.response,
6088
+ });
6089
+ }
6090
+ }
6091
+ /**
6092
+ * Creates breadcrumbs from history API calls
6093
+ */
6094
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6095
+ function _historyBreadcrumb(handlerData) {
6096
+ const global = getGlobalObject();
6097
+ let from = handlerData.from;
6098
+ let to = handlerData.to;
6099
+ const parsedLoc = parseUrl(global.location.href);
6100
+ let parsedFrom = parseUrl(from);
6101
+ const parsedTo = parseUrl(to);
6102
+ // Initial pushState doesn't provide `from` information
6103
+ if (!parsedFrom.path) {
6104
+ parsedFrom = parsedLoc;
6105
+ }
6106
+ // Use only the path component of the URL if the URL matches the current
6107
+ // document (almost all the time when using pushState)
6108
+ if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
6109
+ to = parsedTo.relative;
6110
+ }
6111
+ if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
6112
+ from = parsedFrom.relative;
6113
+ }
6114
+ getCurrentHub().addBreadcrumb({
6115
+ category: 'navigation',
6116
+ data: {
6117
+ from,
6118
+ to,
6119
+ },
6120
+ });
6121
+ }
6291
6122
 
6292
6123
  const DEFAULT_KEY = 'cause';
6293
6124
  const DEFAULT_LIMIT = 5;
@@ -6310,40 +6141,36 @@ var Sentry = (function (exports) {
6310
6141
  setupOnce() {
6311
6142
  addGlobalEventProcessor((event, hint) => {
6312
6143
  const self = getCurrentHub().getIntegration(LinkedErrors);
6313
- if (self) {
6314
- const handler = self._handler && self._handler.bind(self);
6315
- return typeof handler === 'function' ? handler(event, hint) : event;
6316
- }
6317
- return event;
6144
+ return self ? _handler(self._key, self._limit, event, hint) : event;
6318
6145
  });
6319
6146
  }
6320
- /**
6321
- * @inheritDoc
6322
- */
6323
- _handler(event, hint) {
6324
- if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
6325
- return event;
6326
- }
6327
- const linkedErrors = this._walkErrorTree(hint.originalException, this._key);
6328
- event.exception.values = [...linkedErrors, ...event.exception.values];
6147
+ }
6148
+ /**
6149
+ * @inheritDoc
6150
+ */
6151
+ LinkedErrors.id = 'LinkedErrors';
6152
+ /**
6153
+ * @inheritDoc
6154
+ */
6155
+ function _handler(key, limit, event, hint) {
6156
+ if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
6329
6157
  return event;
6330
6158
  }
6331
- /**
6332
- * @inheritDoc
6333
- */
6334
- _walkErrorTree(error, key, stack = []) {
6335
- if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
6336
- return stack;
6337
- }
6338
- const stacktrace = computeStackTrace(error[key]);
6339
- const exception = exceptionFromStacktrace(stacktrace);
6340
- return this._walkErrorTree(error[key], key, [exception, ...stack]);
6341
- }
6159
+ const linkedErrors = _walkErrorTree(limit, hint.originalException, key);
6160
+ event.exception.values = [...linkedErrors, ...event.exception.values];
6161
+ return event;
6342
6162
  }
6343
6163
  /**
6344
- * @inheritDoc
6164
+ * JSDOC
6345
6165
  */
6346
- LinkedErrors.id = 'LinkedErrors';
6166
+ function _walkErrorTree(limit, error, key, stack = []) {
6167
+ if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
6168
+ return stack;
6169
+ }
6170
+ const stacktrace = computeStackTrace(error[key]);
6171
+ const exception = exceptionFromStacktrace(stacktrace);
6172
+ return _walkErrorTree(limit, error[key], key, [exception, ...stack]);
6173
+ }
6347
6174
 
6348
6175
  const global$6 = getGlobalObject();
6349
6176
  /** UserAgent */
@@ -6359,17 +6186,16 @@ var Sentry = (function (exports) {
6359
6186
  */
6360
6187
  setupOnce() {
6361
6188
  addGlobalEventProcessor((event) => {
6362
- var _a, _b, _c;
6363
6189
  if (getCurrentHub().getIntegration(UserAgent)) {
6364
6190
  // if none of the information we want exists, don't bother
6365
6191
  if (!global$6.navigator && !global$6.location && !global$6.document) {
6366
6192
  return event;
6367
6193
  }
6368
6194
  // grab as much info as exists and add it to the event
6369
- const url = ((_a = event.request) === null || _a === void 0 ? void 0 : _a.url) || ((_b = global$6.location) === null || _b === void 0 ? void 0 : _b.href);
6195
+ const url = (event.request && event.request.url) || (global$6.location && global$6.location.href);
6370
6196
  const { referrer } = global$6.document || {};
6371
6197
  const { userAgent } = global$6.navigator || {};
6372
- const headers = Object.assign(Object.assign(Object.assign({}, (_c = event.request) === null || _c === void 0 ? void 0 : _c.headers), (referrer && { Referer: referrer })), (userAgent && { 'User-Agent': userAgent }));
6198
+ const headers = Object.assign(Object.assign(Object.assign({}, (event.request && event.request.headers)), (referrer && { Referer: referrer })), (userAgent && { 'User-Agent': userAgent }));
6373
6199
  const request = Object.assign(Object.assign({}, (url && { url })), { headers });
6374
6200
  return Object.assign(Object.assign({}, event), { request });
6375
6201
  }
@@ -6399,7 +6225,7 @@ var Sentry = (function (exports) {
6399
6225
  if (self) {
6400
6226
  // Juuust in case something goes wrong
6401
6227
  try {
6402
- if (self._shouldDropEvent(currentEvent, self._previousEvent)) {
6228
+ if (_shouldDropEvent(currentEvent, self._previousEvent)) {
6403
6229
  logger.warn(`Event dropped due to being a duplicate of previously captured event.`);
6404
6230
  return null;
6405
6231
  }
@@ -6412,139 +6238,139 @@ var Sentry = (function (exports) {
6412
6238
  return currentEvent;
6413
6239
  });
6414
6240
  }
6415
- /** JSDoc */
6416
- _shouldDropEvent(currentEvent, previousEvent) {
6417
- if (!previousEvent) {
6418
- return false;
6419
- }
6420
- if (this._isSameMessageEvent(currentEvent, previousEvent)) {
6421
- return true;
6422
- }
6423
- if (this._isSameExceptionEvent(currentEvent, previousEvent)) {
6424
- return true;
6425
- }
6241
+ }
6242
+ /**
6243
+ * @inheritDoc
6244
+ */
6245
+ Dedupe.id = 'Dedupe';
6246
+ /** JSDoc */
6247
+ function _shouldDropEvent(currentEvent, previousEvent) {
6248
+ if (!previousEvent) {
6426
6249
  return false;
6427
6250
  }
6428
- /** JSDoc */
6429
- _isSameMessageEvent(currentEvent, previousEvent) {
6430
- const currentMessage = currentEvent.message;
6431
- const previousMessage = previousEvent.message;
6432
- // If neither event has a message property, they were both exceptions, so bail out
6433
- if (!currentMessage && !previousMessage) {
6434
- return false;
6435
- }
6436
- // If only one event has a stacktrace, but not the other one, they are not the same
6437
- if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
6438
- return false;
6439
- }
6440
- if (currentMessage !== previousMessage) {
6441
- return false;
6442
- }
6443
- if (!this._isSameFingerprint(currentEvent, previousEvent)) {
6444
- return false;
6445
- }
6446
- if (!this._isSameStacktrace(currentEvent, previousEvent)) {
6447
- return false;
6448
- }
6251
+ if (_isSameMessageEvent(currentEvent, previousEvent)) {
6449
6252
  return true;
6450
6253
  }
6451
- /** JSDoc */
6452
- _getFramesFromEvent(event) {
6453
- const exception = event.exception;
6454
- if (exception) {
6455
- try {
6456
- // @ts-ignore Object could be undefined
6457
- return exception.values[0].stacktrace.frames;
6458
- }
6459
- catch (_oO) {
6460
- return undefined;
6461
- }
6462
- }
6463
- else if (event.stacktrace) {
6464
- return event.stacktrace.frames;
6465
- }
6466
- return undefined;
6254
+ if (_isSameExceptionEvent(currentEvent, previousEvent)) {
6255
+ return true;
6467
6256
  }
6468
- /** JSDoc */
6469
- _isSameStacktrace(currentEvent, previousEvent) {
6470
- let currentFrames = this._getFramesFromEvent(currentEvent);
6471
- let previousFrames = this._getFramesFromEvent(previousEvent);
6472
- // If neither event has a stacktrace, they are assumed to be the same
6473
- if (!currentFrames && !previousFrames) {
6474
- return true;
6475
- }
6476
- // If only one event has a stacktrace, but not the other one, they are not the same
6477
- if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
6478
- return false;
6479
- }
6480
- currentFrames = currentFrames;
6481
- previousFrames = previousFrames;
6482
- // If number of frames differ, they are not the same
6483
- if (previousFrames.length !== currentFrames.length) {
6484
- return false;
6485
- }
6486
- // Otherwise, compare the two
6487
- for (let i = 0; i < previousFrames.length; i++) {
6488
- const frameA = previousFrames[i];
6489
- const frameB = currentFrames[i];
6490
- if (frameA.filename !== frameB.filename ||
6491
- frameA.lineno !== frameB.lineno ||
6492
- frameA.colno !== frameB.colno ||
6493
- frameA.function !== frameB.function) {
6494
- return false;
6495
- }
6496
- }
6257
+ return false;
6258
+ }
6259
+ /** JSDoc */
6260
+ function _isSameMessageEvent(currentEvent, previousEvent) {
6261
+ const currentMessage = currentEvent.message;
6262
+ const previousMessage = previousEvent.message;
6263
+ // If neither event has a message property, they were both exceptions, so bail out
6264
+ if (!currentMessage && !previousMessage) {
6265
+ return false;
6266
+ }
6267
+ // If only one event has a stacktrace, but not the other one, they are not the same
6268
+ if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
6269
+ return false;
6270
+ }
6271
+ if (currentMessage !== previousMessage) {
6272
+ return false;
6273
+ }
6274
+ if (!_isSameFingerprint(currentEvent, previousEvent)) {
6275
+ return false;
6276
+ }
6277
+ if (!_isSameStacktrace(currentEvent, previousEvent)) {
6278
+ return false;
6279
+ }
6280
+ return true;
6281
+ }
6282
+ /** JSDoc */
6283
+ function _isSameExceptionEvent(currentEvent, previousEvent) {
6284
+ const previousException = _getExceptionFromEvent(previousEvent);
6285
+ const currentException = _getExceptionFromEvent(currentEvent);
6286
+ if (!previousException || !currentException) {
6287
+ return false;
6288
+ }
6289
+ if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
6290
+ return false;
6291
+ }
6292
+ if (!_isSameFingerprint(currentEvent, previousEvent)) {
6293
+ return false;
6294
+ }
6295
+ if (!_isSameStacktrace(currentEvent, previousEvent)) {
6296
+ return false;
6297
+ }
6298
+ return true;
6299
+ }
6300
+ /** JSDoc */
6301
+ function _isSameStacktrace(currentEvent, previousEvent) {
6302
+ let currentFrames = _getFramesFromEvent(currentEvent);
6303
+ let previousFrames = _getFramesFromEvent(previousEvent);
6304
+ // If neither event has a stacktrace, they are assumed to be the same
6305
+ if (!currentFrames && !previousFrames) {
6497
6306
  return true;
6498
6307
  }
6499
- /** JSDoc */
6500
- _getExceptionFromEvent(event) {
6501
- return event.exception && event.exception.values && event.exception.values[0];
6308
+ // If only one event has a stacktrace, but not the other one, they are not the same
6309
+ if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
6310
+ return false;
6502
6311
  }
6503
- /** JSDoc */
6504
- _isSameExceptionEvent(currentEvent, previousEvent) {
6505
- const previousException = this._getExceptionFromEvent(previousEvent);
6506
- const currentException = this._getExceptionFromEvent(currentEvent);
6507
- if (!previousException || !currentException) {
6508
- return false;
6509
- }
6510
- if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
6511
- return false;
6512
- }
6513
- if (!this._isSameFingerprint(currentEvent, previousEvent)) {
6514
- return false;
6515
- }
6516
- if (!this._isSameStacktrace(currentEvent, previousEvent)) {
6312
+ currentFrames = currentFrames;
6313
+ previousFrames = previousFrames;
6314
+ // If number of frames differ, they are not the same
6315
+ if (previousFrames.length !== currentFrames.length) {
6316
+ return false;
6317
+ }
6318
+ // Otherwise, compare the two
6319
+ for (let i = 0; i < previousFrames.length; i++) {
6320
+ const frameA = previousFrames[i];
6321
+ const frameB = currentFrames[i];
6322
+ if (frameA.filename !== frameB.filename ||
6323
+ frameA.lineno !== frameB.lineno ||
6324
+ frameA.colno !== frameB.colno ||
6325
+ frameA.function !== frameB.function) {
6517
6326
  return false;
6518
6327
  }
6328
+ }
6329
+ return true;
6330
+ }
6331
+ /** JSDoc */
6332
+ function _isSameFingerprint(currentEvent, previousEvent) {
6333
+ let currentFingerprint = currentEvent.fingerprint;
6334
+ let previousFingerprint = previousEvent.fingerprint;
6335
+ // If neither event has a fingerprint, they are assumed to be the same
6336
+ if (!currentFingerprint && !previousFingerprint) {
6519
6337
  return true;
6520
6338
  }
6521
- /** JSDoc */
6522
- _isSameFingerprint(currentEvent, previousEvent) {
6523
- let currentFingerprint = currentEvent.fingerprint;
6524
- let previousFingerprint = previousEvent.fingerprint;
6525
- // If neither event has a fingerprint, they are assumed to be the same
6526
- if (!currentFingerprint && !previousFingerprint) {
6527
- return true;
6528
- }
6529
- // If only one event has a fingerprint, but not the other one, they are not the same
6530
- if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
6531
- return false;
6532
- }
6533
- currentFingerprint = currentFingerprint;
6534
- previousFingerprint = previousFingerprint;
6535
- // Otherwise, compare the two
6339
+ // If only one event has a fingerprint, but not the other one, they are not the same
6340
+ if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
6341
+ return false;
6342
+ }
6343
+ currentFingerprint = currentFingerprint;
6344
+ previousFingerprint = previousFingerprint;
6345
+ // Otherwise, compare the two
6346
+ try {
6347
+ return !!(currentFingerprint.join('') === previousFingerprint.join(''));
6348
+ }
6349
+ catch (_oO) {
6350
+ return false;
6351
+ }
6352
+ }
6353
+ /** JSDoc */
6354
+ function _getExceptionFromEvent(event) {
6355
+ return event.exception && event.exception.values && event.exception.values[0];
6356
+ }
6357
+ /** JSDoc */
6358
+ function _getFramesFromEvent(event) {
6359
+ const exception = event.exception;
6360
+ if (exception) {
6536
6361
  try {
6537
- return !!(currentFingerprint.join('') === previousFingerprint.join(''));
6362
+ // @ts-ignore Object could be undefined
6363
+ return exception.values[0].stacktrace.frames;
6538
6364
  }
6539
6365
  catch (_oO) {
6540
- return false;
6366
+ return undefined;
6541
6367
  }
6542
6368
  }
6543
- }
6544
- /**
6545
- * @inheritDoc
6546
- */
6547
- Dedupe.id = 'Dedupe';
6369
+ else if (event.stacktrace) {
6370
+ return event.stacktrace.frames;
6371
+ }
6372
+ return undefined;
6373
+ }
6548
6374
 
6549
6375
 
6550
6376
 
@@ -6763,8 +6589,10 @@ var Sentry = (function (exports) {
6763
6589
  if (client) {
6764
6590
  return client.flush(timeout);
6765
6591
  }
6766
- logger.warn('Cannot flush events. No client defined.');
6767
- return SyncPromise.resolve(false);
6592
+ if (isDebugBuild()) {
6593
+ logger.warn('Cannot flush events. No client defined.');
6594
+ }
6595
+ return resolvedSyncPromise(false);
6768
6596
  }
6769
6597
  /**
6770
6598
  * Call `close()` on the current client, if there is one. See {@link Client.close}.
@@ -6779,8 +6607,10 @@ var Sentry = (function (exports) {
6779
6607
  if (client) {
6780
6608
  return client.close(timeout);
6781
6609
  }
6782
- logger.warn('Cannot flush events and disable SDK. No client defined.');
6783
- return SyncPromise.resolve(false);
6610
+ if (isDebugBuild()) {
6611
+ logger.warn('Cannot flush events and disable SDK. No client defined.');
6612
+ }
6613
+ return resolvedSyncPromise(false);
6784
6614
  }
6785
6615
  /**
6786
6616
  * Wrap code within a try/catch block so the SDK is able to capture errors.
@@ -6793,6 +6623,10 @@ var Sentry = (function (exports) {
6793
6623
  function wrap$1(fn) {
6794
6624
  return wrap(fn)();
6795
6625
  }
6626
+ function startSessionOnHub(hub) {
6627
+ hub.startSession({ ignoreDuration: true });
6628
+ hub.captureSession();
6629
+ }
6796
6630
  /**
6797
6631
  * Enable automatic Session Tracking for the initial page load.
6798
6632
  */
@@ -6800,7 +6634,9 @@ var Sentry = (function (exports) {
6800
6634
  const window = getGlobalObject();
6801
6635
  const document = window.document;
6802
6636
  if (typeof document === 'undefined') {
6803
- logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
6637
+ if (isDebugBuild()) {
6638
+ logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
6639
+ }
6804
6640
  return;
6805
6641
  }
6806
6642
  const hub = getCurrentHub();
@@ -6810,26 +6646,20 @@ var Sentry = (function (exports) {
6810
6646
  // https://github.com/getsentry/sentry-javascript/issues/3207 and
6811
6647
  // https://github.com/getsentry/sentry-javascript/issues/3234 and
6812
6648
  // https://github.com/getsentry/sentry-javascript/issues/3278.
6813
- if (typeof hub.startSession !== 'function' || typeof hub.captureSession !== 'function') {
6649
+ if (!hub.captureSession) {
6814
6650
  return;
6815
6651
  }
6816
6652
  // The session duration for browser sessions does not track a meaningful
6817
6653
  // concept that can be used as a metric.
6818
6654
  // Automatically captured sessions are akin to page views, and thus we
6819
6655
  // discard their duration.
6820
- hub.startSession({ ignoreDuration: true });
6821
- hub.captureSession();
6656
+ startSessionOnHub(hub);
6822
6657
  // We want to create a session for every navigation as well
6823
- addInstrumentationHandler({
6824
- callback: ({ from, to }) => {
6825
- // Don't create an additional session for the initial route or if the location did not change
6826
- if (from === undefined || from === to) {
6827
- return;
6828
- }
6829
- hub.startSession({ ignoreDuration: true });
6830
- hub.captureSession();
6831
- },
6832
- type: 'history',
6658
+ addInstrumentationHandler('history', ({ from, to }) => {
6659
+ // Don't create an additional session for the initial route or if the location did not change
6660
+ if (!(from === undefined || from === to)) {
6661
+ startSessionOnHub(getCurrentHub());
6662
+ }
6833
6663
  });
6834
6664
  }
6835
6665