@sentry/browser 6.13.2 → 6.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/build/bundle.es6.js +455 -354
  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 +456 -356
  6. package/build/bundle.js.map +1 -1
  7. package/build/bundle.min.js +2 -2
  8. package/build/bundle.min.js.map +1 -1
  9. package/dist/eventbuilder.d.ts.map +1 -1
  10. package/dist/eventbuilder.js +3 -7
  11. package/dist/eventbuilder.js.map +1 -1
  12. package/dist/integrations/trycatch.js +1 -1
  13. package/dist/integrations/trycatch.js.map +1 -1
  14. package/dist/transports/base.d.ts.map +1 -1
  15. package/dist/transports/base.js +8 -6
  16. package/dist/transports/base.js.map +1 -1
  17. package/dist/transports/fetch.d.ts +1 -2
  18. package/dist/transports/fetch.d.ts.map +1 -1
  19. package/dist/transports/fetch.js +2 -67
  20. package/dist/transports/fetch.js.map +1 -1
  21. package/dist/transports/utils.d.ts +48 -0
  22. package/dist/transports/utils.d.ts.map +1 -0
  23. package/dist/transports/utils.js +99 -0
  24. package/dist/transports/utils.js.map +1 -0
  25. package/dist/transports/xhr.js +1 -1
  26. package/dist/transports/xhr.js.map +1 -1
  27. package/esm/eventbuilder.d.ts.map +1 -1
  28. package/esm/eventbuilder.js +3 -7
  29. package/esm/eventbuilder.js.map +1 -1
  30. package/esm/integrations/trycatch.js +1 -1
  31. package/esm/integrations/trycatch.js.map +1 -1
  32. package/esm/transports/base.d.ts.map +1 -1
  33. package/esm/transports/base.js +9 -7
  34. package/esm/transports/base.js.map +1 -1
  35. package/esm/transports/fetch.d.ts +1 -2
  36. package/esm/transports/fetch.d.ts.map +1 -1
  37. package/esm/transports/fetch.js +2 -67
  38. package/esm/transports/fetch.js.map +1 -1
  39. package/esm/transports/utils.d.ts +48 -0
  40. package/esm/transports/utils.d.ts.map +1 -0
  41. package/esm/transports/utils.js +96 -0
  42. package/esm/transports/utils.js.map +1 -0
  43. package/esm/transports/xhr.js +1 -1
  44. package/esm/transports/xhr.js.map +1 -1
  45. package/package.json +23 -23
@@ -1,4 +1,4 @@
1
- /*! @sentry/browser 6.13.2 (1de7a04) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.14.2 (9a623dd) | https://github.com/getsentry/sentry-javascript */
2
2
  var Sentry = (function (exports) {
3
3
  /** Console logging verbosity for the SDK. */
4
4
  var LogLevel;
@@ -144,6 +144,62 @@ var Sentry = (function (exports) {
144
144
  Outcome["SampleRate"] = "sample_rate";
145
145
  })(Outcome || (Outcome = {}));
146
146
 
147
+ /**
148
+ * Consumes the promise and logs the error when it rejects.
149
+ * @param promise A promise to forget.
150
+ */
151
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
+ function forget(promise) {
153
+ void promise.then(null, e => {
154
+ // TODO: Use a better logging mechanism
155
+ // eslint-disable-next-line no-console
156
+ console.error(e);
157
+ });
158
+ }
159
+
160
+ /**
161
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
162
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
163
+ */
164
+ /**
165
+ * Checks whether we're in the Node.js or Browser environment
166
+ *
167
+ * @returns Answer to given question
168
+ */
169
+ function isNodeEnv() {
170
+ return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
171
+ }
172
+ /**
173
+ * Requires a module which is protected against bundler minification.
174
+ *
175
+ * @param request The module path to resolve
176
+ */
177
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
178
+ function dynamicRequire(mod, request) {
179
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
180
+ return mod.require(request);
181
+ }
182
+
183
+ /**
184
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
185
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
186
+ */
187
+ const fallbackGlobalObject = {};
188
+ /**
189
+ * Safely get global scope object
190
+ *
191
+ * @returns Global scope object
192
+ */
193
+ function getGlobalObject() {
194
+ return (isNodeEnv()
195
+ ? global
196
+ : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
197
+ ? window // eslint-disable-line no-restricted-globals
198
+ : typeof self !== 'undefined'
199
+ ? self
200
+ : fallbackGlobalObject);
201
+ }
202
+
147
203
  /* eslint-disable @typescript-eslint/no-explicit-any */
148
204
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
149
205
  /**
@@ -196,7 +252,7 @@ var Sentry = (function (exports) {
196
252
  return Object.prototype.toString.call(wat) === '[object DOMException]';
197
253
  }
198
254
  /**
199
- * Checks whether given value's type is a string
255
+ * Checks whether the given value's type is string
200
256
  * {@link isString}.
201
257
  *
202
258
  * @param wat A value to be checked.
@@ -379,6 +435,18 @@ var Sentry = (function (exports) {
379
435
  }
380
436
  }
381
437
  return out.join('');
438
+ }
439
+ /**
440
+ * A safe form of location.href
441
+ */
442
+ function getLocationHref() {
443
+ const global = getGlobalObject();
444
+ try {
445
+ return global.document.location.href;
446
+ }
447
+ catch (oO) {
448
+ return '';
449
+ }
382
450
  }
383
451
 
384
452
  const setPrototypeOf = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties);
@@ -397,8 +465,7 @@ var Sentry = (function (exports) {
397
465
  // eslint-disable-next-line @typescript-eslint/ban-types
398
466
  function mixinProperties(obj, proto) {
399
467
  for (const prop in proto) {
400
- // eslint-disable-next-line no-prototype-builtins
401
- if (!obj.hasOwnProperty(prop)) {
468
+ if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
402
469
  // @ts-ignore typescript complains about indexing so we remove
403
470
  obj[prop] = proto[prop];
404
471
  }
@@ -502,174 +569,17 @@ var Sentry = (function (exports) {
502
569
  }
503
570
  }
504
571
 
572
+ // TODO: Implement different loggers for different environments
573
+ const global$1 = getGlobalObject();
574
+ /** Prefix for logging strings */
575
+ const PREFIX = 'Sentry Logger ';
505
576
  /**
506
- * Checks whether we're in the Node.js or Browser environment
507
- *
508
- * @returns Answer to given question
509
- */
510
- function isNodeEnv() {
511
- return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
512
- }
513
- /**
514
- * Requires a module which is protected against bundler minification.
515
- *
516
- * @param request The module path to resolve
517
- */
518
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
519
- function dynamicRequire(mod, request) {
520
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
521
- return mod.require(request);
522
- }
523
-
524
- /**
525
- * Truncates given string to the maximum characters count
526
- *
527
- * @param str An object that contains serializable values
528
- * @param max Maximum number of characters in truncated string (0 = unlimited)
529
- * @returns string Encoded
530
- */
531
- function truncate(str, max = 0) {
532
- if (typeof str !== 'string' || max === 0) {
533
- return str;
534
- }
535
- return str.length <= max ? str : `${str.substr(0, max)}...`;
536
- }
537
- /**
538
- * Join values in array
539
- * @param input array of values to be joined together
540
- * @param delimiter string to be placed in-between values
541
- * @returns Joined values
542
- */
543
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
544
- function safeJoin(input, delimiter) {
545
- if (!Array.isArray(input)) {
546
- return '';
547
- }
548
- const output = [];
549
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
550
- for (let i = 0; i < input.length; i++) {
551
- const value = input[i];
552
- try {
553
- output.push(String(value));
554
- }
555
- catch (e) {
556
- output.push('[value cannot be serialized]');
557
- }
558
- }
559
- return output.join(delimiter);
560
- }
561
- /**
562
- * Checks if the value matches a regex or includes the string
563
- * @param value The string value to be checked against
564
- * @param pattern Either a regex or a string that must be contained in value
565
- */
566
- function isMatchingPattern(value, pattern) {
567
- if (!isString(value)) {
568
- return false;
569
- }
570
- if (isRegExp(pattern)) {
571
- return pattern.test(value);
572
- }
573
- if (typeof pattern === 'string') {
574
- return value.indexOf(pattern) !== -1;
575
- }
576
- return false;
577
- }
578
-
579
- const fallbackGlobalObject = {};
580
- /**
581
- * Safely get global scope object
582
- *
583
- * @returns Global scope object
584
- */
585
- function getGlobalObject() {
586
- return (isNodeEnv()
587
- ? global
588
- : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
589
- ? window // eslint-disable-line no-restricted-globals
590
- : typeof self !== 'undefined'
591
- ? self
592
- : fallbackGlobalObject);
593
- }
594
- /**
595
- * UUID4 generator
577
+ * Temporarily unwrap `console.log` and friends in order to perform the given callback using the original methods.
578
+ * Restores wrapping after the callback completes.
596
579
  *
597
- * @returns string Generated UUID4.
598
- */
599
- function uuid4() {
600
- const global = getGlobalObject();
601
- const crypto = global.crypto || global.msCrypto;
602
- if (!(crypto === void 0) && crypto.getRandomValues) {
603
- // Use window.crypto API if available
604
- const arr = new Uint16Array(8);
605
- crypto.getRandomValues(arr);
606
- // set 4 in byte 7
607
- // eslint-disable-next-line no-bitwise
608
- arr[3] = (arr[3] & 0xfff) | 0x4000;
609
- // set 2 most significant bits of byte 9 to '10'
610
- // eslint-disable-next-line no-bitwise
611
- arr[4] = (arr[4] & 0x3fff) | 0x8000;
612
- const pad = (num) => {
613
- let v = num.toString(16);
614
- while (v.length < 4) {
615
- v = `0${v}`;
616
- }
617
- return v;
618
- };
619
- return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + pad(arr[5]) + pad(arr[6]) + pad(arr[7]));
620
- }
621
- // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
622
- return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
623
- // eslint-disable-next-line no-bitwise
624
- const r = (Math.random() * 16) | 0;
625
- // eslint-disable-next-line no-bitwise
626
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
627
- return v.toString(16);
628
- });
629
- }
630
- /**
631
- * Parses string form of URL into an object
632
- * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
633
- * // intentionally using regex and not <a/> href parsing trick because React Native and other
634
- * // environments where DOM might not be available
635
- * @returns parsed URL object
580
+ * @param callback The function to run against the original `console` messages
581
+ * @returns The results of the callback
636
582
  */
637
- function parseUrl(url) {
638
- if (!url) {
639
- return {};
640
- }
641
- const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
642
- if (!match) {
643
- return {};
644
- }
645
- // coerce to undefined values to empty string so we don't get 'undefined'
646
- const query = match[6] || '';
647
- const fragment = match[8] || '';
648
- return {
649
- host: match[4],
650
- path: match[5],
651
- protocol: match[2],
652
- relative: match[5] + query + fragment,
653
- };
654
- }
655
- /**
656
- * Extracts either message or type+value from an event that can be used for user-facing logs
657
- * @returns event's description
658
- */
659
- function getEventDescription(event) {
660
- if (event.message) {
661
- return event.message;
662
- }
663
- if (event.exception && event.exception.values && event.exception.values[0]) {
664
- const exception = event.exception.values[0];
665
- if (exception.type && exception.value) {
666
- return `${exception.type}: ${exception.value}`;
667
- }
668
- return exception.type || exception.value || event.event_id || '<unknown>';
669
- }
670
- return event.event_id || '<unknown>';
671
- }
672
- /** JSDoc */
673
583
  function consoleSandbox(callback) {
674
584
  const global = getGlobalObject();
675
585
  const levels = ['debug', 'info', 'warn', 'error', 'log', 'assert'];
@@ -695,80 +605,6 @@ var Sentry = (function (exports) {
695
605
  });
696
606
  return result;
697
607
  }
698
- /**
699
- * Adds exception values, type and value to an synthetic Exception.
700
- * @param event The event to modify.
701
- * @param value Value of the exception.
702
- * @param type Type of the exception.
703
- * @hidden
704
- */
705
- function addExceptionTypeValue(event, value, type) {
706
- event.exception = event.exception || {};
707
- event.exception.values = event.exception.values || [];
708
- event.exception.values[0] = event.exception.values[0] || {};
709
- event.exception.values[0].value = event.exception.values[0].value || value || '';
710
- event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
711
- }
712
- /**
713
- * Adds exception mechanism to a given event.
714
- * @param event The event to modify.
715
- * @param mechanism Mechanism of the mechanism.
716
- * @hidden
717
- */
718
- function addExceptionMechanism(event, mechanism = {}) {
719
- // TODO: Use real type with `keyof Mechanism` thingy and maybe make it better?
720
- try {
721
- // @ts-ignore Type 'Mechanism | {}' is not assignable to type 'Mechanism | undefined'
722
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
723
- event.exception.values[0].mechanism = event.exception.values[0].mechanism || {};
724
- Object.keys(mechanism).forEach(key => {
725
- // @ts-ignore Mechanism has no index signature
726
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
727
- event.exception.values[0].mechanism[key] = mechanism[key];
728
- });
729
- }
730
- catch (_oO) {
731
- // no-empty
732
- }
733
- }
734
- /**
735
- * A safe form of location.href
736
- */
737
- function getLocationHref() {
738
- const global = getGlobalObject();
739
- try {
740
- return global.document.location.href;
741
- }
742
- catch (oO) {
743
- return '';
744
- }
745
- }
746
- const defaultRetryAfter = 60 * 1000; // 60 seconds
747
- /**
748
- * Extracts Retry-After value from the request header or returns default value
749
- * @param now current unix timestamp
750
- * @param header string representation of 'Retry-After' header
751
- */
752
- function parseRetryAfterHeader(now, header) {
753
- if (!header) {
754
- return defaultRetryAfter;
755
- }
756
- const headerDelay = parseInt(`${header}`, 10);
757
- if (!isNaN(headerDelay)) {
758
- return headerDelay * 1000;
759
- }
760
- const headerDate = Date.parse(`${header}`);
761
- if (!isNaN(headerDate)) {
762
- return headerDate - now;
763
- }
764
- return defaultRetryAfter;
765
- }
766
-
767
- /* eslint-disable @typescript-eslint/no-explicit-any */
768
- // TODO: Implement different loggers for different environments
769
- const global$1 = getGlobalObject();
770
- /** Prefix for logging strings */
771
- const PREFIX = 'Sentry Logger ';
772
608
  /** JSDoc */
773
609
  class Logger {
774
610
  /** JSDoc */
@@ -885,6 +721,61 @@ var Sentry = (function (exports) {
885
721
  }
886
722
  }
887
723
 
724
+ /**
725
+ * Truncates given string to the maximum characters count
726
+ *
727
+ * @param str An object that contains serializable values
728
+ * @param max Maximum number of characters in truncated string (0 = unlimited)
729
+ * @returns string Encoded
730
+ */
731
+ function truncate(str, max = 0) {
732
+ if (typeof str !== 'string' || max === 0) {
733
+ return str;
734
+ }
735
+ return str.length <= max ? str : `${str.substr(0, max)}...`;
736
+ }
737
+ /**
738
+ * Join values in array
739
+ * @param input array of values to be joined together
740
+ * @param delimiter string to be placed in-between values
741
+ * @returns Joined values
742
+ */
743
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
744
+ function safeJoin(input, delimiter) {
745
+ if (!Array.isArray(input)) {
746
+ return '';
747
+ }
748
+ const output = [];
749
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
750
+ for (let i = 0; i < input.length; i++) {
751
+ const value = input[i];
752
+ try {
753
+ output.push(String(value));
754
+ }
755
+ catch (e) {
756
+ output.push('[value cannot be serialized]');
757
+ }
758
+ }
759
+ return output.join(delimiter);
760
+ }
761
+ /**
762
+ * Checks if the value matches a regex or includes the string
763
+ * @param value The string value to be checked against
764
+ * @param pattern Either a regex or a string that must be contained in value
765
+ */
766
+ function isMatchingPattern(value, pattern) {
767
+ if (!isString(value)) {
768
+ return false;
769
+ }
770
+ if (isRegExp(pattern)) {
771
+ return pattern.test(value);
772
+ }
773
+ if (typeof pattern === 'string') {
774
+ return value.indexOf(pattern) !== -1;
775
+ }
776
+ return false;
777
+ }
778
+
888
779
  /**
889
780
  * Replace a method in an object with a wrapped version of itself.
890
781
  *
@@ -1183,9 +1074,8 @@ var Sentry = (function (exports) {
1183
1074
  * Given any object, return the new object with removed keys that value was `undefined`.
1184
1075
  * Works recursively on objects and arrays.
1185
1076
  */
1186
- function dropUndefinedKeys(val) {
1187
- if (isPlainObject(val)) {
1188
- const obj = val;
1077
+ function dropUndefinedKeys(obj) {
1078
+ if (isPlainObject(obj)) {
1189
1079
  const rv = {};
1190
1080
  for (const key of Object.keys(obj)) {
1191
1081
  if (typeof obj[key] !== 'undefined') {
@@ -1194,10 +1084,10 @@ var Sentry = (function (exports) {
1194
1084
  }
1195
1085
  return rv;
1196
1086
  }
1197
- if (Array.isArray(val)) {
1198
- return val.map(dropUndefinedKeys);
1087
+ if (Array.isArray(obj)) {
1088
+ return obj.map(dropUndefinedKeys);
1199
1089
  }
1200
- return val;
1090
+ return obj;
1201
1091
  }
1202
1092
 
1203
1093
  /**
@@ -1788,18 +1678,191 @@ var Sentry = (function (exports) {
1788
1678
  return false;
1789
1679
  };
1790
1680
  }
1791
- let _oldOnUnhandledRejectionHandler = null;
1792
- /** JSDoc */
1793
- function instrumentUnhandledRejection() {
1794
- _oldOnUnhandledRejectionHandler = global$2.onunhandledrejection;
1795
- global$2.onunhandledrejection = function (e) {
1796
- triggerHandlers('unhandledrejection', e);
1797
- if (_oldOnUnhandledRejectionHandler) {
1798
- // eslint-disable-next-line prefer-rest-params
1799
- return _oldOnUnhandledRejectionHandler.apply(this, arguments);
1681
+ let _oldOnUnhandledRejectionHandler = null;
1682
+ /** JSDoc */
1683
+ function instrumentUnhandledRejection() {
1684
+ _oldOnUnhandledRejectionHandler = global$2.onunhandledrejection;
1685
+ global$2.onunhandledrejection = function (e) {
1686
+ triggerHandlers('unhandledrejection', e);
1687
+ if (_oldOnUnhandledRejectionHandler) {
1688
+ // eslint-disable-next-line prefer-rest-params
1689
+ return _oldOnUnhandledRejectionHandler.apply(this, arguments);
1690
+ }
1691
+ return true;
1692
+ };
1693
+ }
1694
+
1695
+ /**
1696
+ * UUID4 generator
1697
+ *
1698
+ * @returns string Generated UUID4.
1699
+ */
1700
+ function uuid4() {
1701
+ const global = getGlobalObject();
1702
+ const crypto = global.crypto || global.msCrypto;
1703
+ if (!(crypto === void 0) && crypto.getRandomValues) {
1704
+ // Use window.crypto API if available
1705
+ const arr = new Uint16Array(8);
1706
+ crypto.getRandomValues(arr);
1707
+ // set 4 in byte 7
1708
+ // eslint-disable-next-line no-bitwise
1709
+ arr[3] = (arr[3] & 0xfff) | 0x4000;
1710
+ // set 2 most significant bits of byte 9 to '10'
1711
+ // eslint-disable-next-line no-bitwise
1712
+ arr[4] = (arr[4] & 0x3fff) | 0x8000;
1713
+ const pad = (num) => {
1714
+ let v = num.toString(16);
1715
+ while (v.length < 4) {
1716
+ v = `0${v}`;
1717
+ }
1718
+ return v;
1719
+ };
1720
+ return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + pad(arr[5]) + pad(arr[6]) + pad(arr[7]));
1721
+ }
1722
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
1723
+ return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
1724
+ // eslint-disable-next-line no-bitwise
1725
+ const r = (Math.random() * 16) | 0;
1726
+ // eslint-disable-next-line no-bitwise
1727
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
1728
+ return v.toString(16);
1729
+ });
1730
+ }
1731
+ /**
1732
+ * Parses string form of URL into an object
1733
+ * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
1734
+ * // intentionally using regex and not <a/> href parsing trick because React Native and other
1735
+ * // environments where DOM might not be available
1736
+ * @returns parsed URL object
1737
+ */
1738
+ function parseUrl(url) {
1739
+ if (!url) {
1740
+ return {};
1741
+ }
1742
+ const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
1743
+ if (!match) {
1744
+ return {};
1745
+ }
1746
+ // coerce to undefined values to empty string so we don't get 'undefined'
1747
+ const query = match[6] || '';
1748
+ const fragment = match[8] || '';
1749
+ return {
1750
+ host: match[4],
1751
+ path: match[5],
1752
+ protocol: match[2],
1753
+ relative: match[5] + query + fragment,
1754
+ };
1755
+ }
1756
+ /**
1757
+ * Extracts either message or type+value from an event that can be used for user-facing logs
1758
+ * @returns event's description
1759
+ */
1760
+ function getEventDescription(event) {
1761
+ if (event.message) {
1762
+ return event.message;
1763
+ }
1764
+ if (event.exception && event.exception.values && event.exception.values[0]) {
1765
+ const exception = event.exception.values[0];
1766
+ if (exception.type && exception.value) {
1767
+ return `${exception.type}: ${exception.value}`;
1800
1768
  }
1769
+ return exception.type || exception.value || event.event_id || '<unknown>';
1770
+ }
1771
+ return event.event_id || '<unknown>';
1772
+ }
1773
+ /**
1774
+ * Adds exception values, type and value to an synthetic Exception.
1775
+ * @param event The event to modify.
1776
+ * @param value Value of the exception.
1777
+ * @param type Type of the exception.
1778
+ * @hidden
1779
+ */
1780
+ function addExceptionTypeValue(event, value, type) {
1781
+ event.exception = event.exception || {};
1782
+ event.exception.values = event.exception.values || [];
1783
+ event.exception.values[0] = event.exception.values[0] || {};
1784
+ event.exception.values[0].value = event.exception.values[0].value || value || '';
1785
+ event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
1786
+ }
1787
+ /**
1788
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
1789
+ *
1790
+ * @param event The event to modify.
1791
+ * @param newMechanism Mechanism data to add to the event.
1792
+ * @hidden
1793
+ */
1794
+ function addExceptionMechanism(event, newMechanism) {
1795
+ var _a;
1796
+ if (!event.exception || !event.exception.values) {
1797
+ return;
1798
+ }
1799
+ const exceptionValue0 = event.exception.values[0];
1800
+ const defaultMechanism = { type: 'generic', handled: true };
1801
+ const currentMechanism = exceptionValue0.mechanism;
1802
+ exceptionValue0.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
1803
+ if (newMechanism && 'data' in newMechanism) {
1804
+ const mergedData = Object.assign(Object.assign({}, (_a = currentMechanism) === null || _a === void 0 ? void 0 : _a.data), newMechanism.data);
1805
+ exceptionValue0.mechanism.data = mergedData;
1806
+ }
1807
+ }
1808
+ const defaultRetryAfter = 60 * 1000; // 60 seconds
1809
+ /**
1810
+ * Extracts Retry-After value from the request header or returns default value
1811
+ * @param now current unix timestamp
1812
+ * @param header string representation of 'Retry-After' header
1813
+ */
1814
+ function parseRetryAfterHeader(now, header) {
1815
+ if (!header) {
1816
+ return defaultRetryAfter;
1817
+ }
1818
+ const headerDelay = parseInt(`${header}`, 10);
1819
+ if (!isNaN(headerDelay)) {
1820
+ return headerDelay * 1000;
1821
+ }
1822
+ const headerDate = Date.parse(`${header}`);
1823
+ if (!isNaN(headerDate)) {
1824
+ return headerDate - now;
1825
+ }
1826
+ return defaultRetryAfter;
1827
+ }
1828
+ /**
1829
+ * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
1830
+ * in question), and marks it captured if not.
1831
+ *
1832
+ * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
1833
+ * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
1834
+ * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
1835
+ * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
1836
+ * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
1837
+ * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
1838
+ * see it.
1839
+ *
1840
+ * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
1841
+ * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
1842
+ * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
1843
+ * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
1844
+ * must be done before the exception captured.
1845
+ *
1846
+ * @param A thrown exception to check or flag as having been seen
1847
+ * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
1848
+ */
1849
+ function checkOrSetAlreadyCaught(exception) {
1850
+ var _a;
1851
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1852
+ if ((_a = exception) === null || _a === void 0 ? void 0 : _a.__sentry_captured__) {
1801
1853
  return true;
1802
- };
1854
+ }
1855
+ try {
1856
+ // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
1857
+ // `ExtraErrorData` integration
1858
+ Object.defineProperty(exception, '__sentry_captured__', {
1859
+ value: true,
1860
+ });
1861
+ }
1862
+ catch (err) {
1863
+ // `exception` is a primitive, so we can't mark it seen
1864
+ }
1865
+ return false;
1803
1866
  }
1804
1867
 
1805
1868
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
@@ -3607,6 +3670,7 @@ var Sentry = (function (exports) {
3607
3670
  }
3608
3671
 
3609
3672
  /* eslint-disable max-lines */
3673
+ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
3610
3674
  /**
3611
3675
  * Base implementation for all JavaScript SDK clients.
3612
3676
  *
@@ -3662,6 +3726,11 @@ var Sentry = (function (exports) {
3662
3726
  */
3663
3727
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
3664
3728
  captureException(exception, hint, scope) {
3729
+ // ensure we haven't captured this very object before
3730
+ if (checkOrSetAlreadyCaught(exception)) {
3731
+ logger.log(ALREADY_SEEN_ERROR);
3732
+ return;
3733
+ }
3665
3734
  let eventId = hint && hint.event_id;
3666
3735
  this._process(this._getBackend()
3667
3736
  .eventFromException(exception, hint)
@@ -3690,6 +3759,12 @@ var Sentry = (function (exports) {
3690
3759
  * @inheritDoc
3691
3760
  */
3692
3761
  captureEvent(event, hint, scope) {
3762
+ var _a;
3763
+ // ensure we haven't captured this very object before
3764
+ if (((_a = hint) === null || _a === void 0 ? void 0 : _a.originalException) && checkOrSetAlreadyCaught(hint.originalException)) {
3765
+ logger.log(ALREADY_SEEN_ERROR);
3766
+ return;
3767
+ }
3693
3768
  let eventId = hint && hint.event_id;
3694
3769
  this._process(this._captureEvent(event, hint, scope).then(result => {
3695
3770
  eventId = result;
@@ -4285,7 +4360,7 @@ var Sentry = (function (exports) {
4285
4360
  hub.bindClient(client);
4286
4361
  }
4287
4362
 
4288
- const SDK_VERSION = '6.13.2';
4363
+ const SDK_VERSION = '6.14.2';
4289
4364
 
4290
4365
  let originalFunctionToString;
4291
4366
  /** Patch toString calls to return proper name for wrapped functions */
@@ -4856,10 +4931,7 @@ var Sentry = (function (exports) {
4856
4931
  const event = eventFromUnknownInput(exception, syntheticException, {
4857
4932
  attachStacktrace: options.attachStacktrace,
4858
4933
  });
4859
- addExceptionMechanism(event, {
4860
- handled: true,
4861
- type: 'generic',
4862
- });
4934
+ addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
4863
4935
  event.level = exports.Severity.Error;
4864
4936
  if (hint && hint.event_id) {
4865
4937
  event.event_id = hint.event_id;
@@ -4886,11 +4958,10 @@ var Sentry = (function (exports) {
4886
4958
  */
4887
4959
  function eventFromUnknownInput(exception, syntheticException, options = {}) {
4888
4960
  let event;
4889
- if (isErrorEvent(exception) && exception.error) {
4961
+ if (isErrorEvent(exception)) {
4890
4962
  // If it is an ErrorEvent with `error` property, extract it to get actual Error
4891
- const errorEvent = exception;
4892
4963
  // eslint-disable-next-line no-param-reassign
4893
- exception = errorEvent.error;
4964
+ exception = exception.error;
4894
4965
  event = eventFromStacktrace(computeStackTrace(exception));
4895
4966
  return event;
4896
4967
  }
@@ -4958,13 +5029,108 @@ var Sentry = (function (exports) {
4958
5029
  return event;
4959
5030
  }
4960
5031
 
5032
+ const global$3 = getGlobalObject();
5033
+ let cachedFetchImpl;
5034
+ /**
5035
+ * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
5036
+ * Whenever someone wraps the Fetch API and returns the wrong promise chain,
5037
+ * this chain becomes orphaned and there is no possible way to capture it's rejections
5038
+ * other than allowing it bubble up to this very handler. eg.
5039
+ *
5040
+ * const f = window.fetch;
5041
+ * window.fetch = function () {
5042
+ * const p = f.apply(this, arguments);
5043
+ *
5044
+ * p.then(function() {
5045
+ * console.log('hi.');
5046
+ * });
5047
+ *
5048
+ * return p;
5049
+ * }
5050
+ *
5051
+ * `p.then(function () { ... })` is producing a completely separate promise chain,
5052
+ * however, what's returned is `p` - the result of original `fetch` call.
5053
+ *
5054
+ * This mean, that whenever we use the Fetch API to send our own requests, _and_
5055
+ * some ad-blocker blocks it, this orphaned chain will _always_ reject,
5056
+ * effectively causing another event to be captured.
5057
+ * This makes a whole process become an infinite loop, which we need to somehow
5058
+ * deal with, and break it in one way or another.
5059
+ *
5060
+ * To deal with this issue, we are making sure that we _always_ use the real
5061
+ * browser Fetch API, instead of relying on what `window.fetch` exposes.
5062
+ * The only downside to this would be missing our own requests as breadcrumbs,
5063
+ * but because we are already not doing this, it should be just fine.
5064
+ *
5065
+ * Possible failed fetch error messages per-browser:
5066
+ *
5067
+ * Chrome: Failed to fetch
5068
+ * Edge: Failed to Fetch
5069
+ * Firefox: NetworkError when attempting to fetch resource
5070
+ * Safari: resource blocked by content blocker
5071
+ */
5072
+ function getNativeFetchImplementation() {
5073
+ var _a, _b;
5074
+ if (cachedFetchImpl) {
5075
+ return cachedFetchImpl;
5076
+ }
5077
+ /* eslint-disable @typescript-eslint/unbound-method */
5078
+ // Fast path to avoid DOM I/O
5079
+ if (isNativeFetch(global$3.fetch)) {
5080
+ return (cachedFetchImpl = global$3.fetch.bind(global$3));
5081
+ }
5082
+ const document = global$3.document;
5083
+ let fetchImpl = global$3.fetch;
5084
+ // eslint-disable-next-line deprecation/deprecation
5085
+ if (typeof ((_a = document) === null || _a === void 0 ? void 0 : _a.createElement) === `function`) {
5086
+ try {
5087
+ const sandbox = document.createElement('iframe');
5088
+ sandbox.hidden = true;
5089
+ document.head.appendChild(sandbox);
5090
+ if ((_b = sandbox.contentWindow) === null || _b === void 0 ? void 0 : _b.fetch) {
5091
+ fetchImpl = sandbox.contentWindow.fetch;
5092
+ }
5093
+ document.head.removeChild(sandbox);
5094
+ }
5095
+ catch (e) {
5096
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
5097
+ }
5098
+ }
5099
+ return (cachedFetchImpl = fetchImpl.bind(global$3));
5100
+ /* eslint-enable @typescript-eslint/unbound-method */
5101
+ }
5102
+ /**
5103
+ * Sends sdk client report using sendBeacon or fetch as a fallback if available
5104
+ *
5105
+ * @param url report endpoint
5106
+ * @param body report payload
5107
+ */
5108
+ function sendReport(url, body) {
5109
+ const isRealNavigator = Object.prototype.toString.call(global$3 && global$3.navigator) === '[object Navigator]';
5110
+ const hasSendBeacon = isRealNavigator && typeof global$3.navigator.sendBeacon === 'function';
5111
+ if (hasSendBeacon) {
5112
+ // Prevent illegal invocations - https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
5113
+ const sendBeacon = global$3.navigator.sendBeacon.bind(global$3.navigator);
5114
+ return sendBeacon(url, body);
5115
+ }
5116
+ if (supportsFetch()) {
5117
+ const fetch = getNativeFetchImplementation();
5118
+ return forget(fetch(url, {
5119
+ body,
5120
+ method: 'POST',
5121
+ credentials: 'omit',
5122
+ keepalive: true,
5123
+ }));
5124
+ }
5125
+ }
5126
+
4961
5127
  const CATEGORY_MAPPING = {
4962
5128
  event: 'error',
4963
5129
  transaction: 'transaction',
4964
5130
  session: 'session',
4965
5131
  attachment: 'attachment',
4966
5132
  };
4967
- const global$3 = getGlobalObject();
5133
+ const global$4 = getGlobalObject();
4968
5134
  /** Base Transport class implementation */
4969
5135
  class BaseTransport {
4970
5136
  constructor(options) {
@@ -4977,9 +5143,9 @@ var Sentry = (function (exports) {
4977
5143
  this._api = new API(options.dsn, options._metadata, options.tunnel);
4978
5144
  // eslint-disable-next-line deprecation/deprecation
4979
5145
  this.url = this._api.getStoreEndpointWithUrlEncodedAuth();
4980
- if (this.options.sendClientReports && global$3.document) {
4981
- global$3.document.addEventListener('visibilitychange', () => {
4982
- if (global$3.document.visibilityState === 'hidden') {
5146
+ if (this.options.sendClientReports && global$4.document) {
5147
+ global$4.document.addEventListener('visibilitychange', () => {
5148
+ if (global$4.document.visibilityState === 'hidden') {
4983
5149
  this._flushOutcomes();
4984
5150
  }
4985
5151
  });
@@ -5021,10 +5187,6 @@ var Sentry = (function (exports) {
5021
5187
  if (!this.options.sendClientReports) {
5022
5188
  return;
5023
5189
  }
5024
- if (!global$3.navigator || typeof global$3.navigator.sendBeacon !== 'function') {
5025
- logger.warn('Beacon API not available, skipping sending outcomes.');
5026
- return;
5027
- }
5028
5190
  const outcomes = this._outcomes;
5029
5191
  this._outcomes = {};
5030
5192
  // Nothing to send
@@ -5035,7 +5197,7 @@ var Sentry = (function (exports) {
5035
5197
  logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
5036
5198
  const url = this._api.getEnvelopeEndpointWithUrlEncodedAuth();
5037
5199
  // Envelope header is required to be at least an empty object
5038
- const envelopeHeader = JSON.stringify({});
5200
+ const envelopeHeader = JSON.stringify(Object.assign({}, (this.options.tunnel && { dsn: this._api.getDsn().toString() })));
5039
5201
  const itemHeaders = JSON.stringify({
5040
5202
  type: 'client_report',
5041
5203
  });
@@ -5051,7 +5213,12 @@ var Sentry = (function (exports) {
5051
5213
  }),
5052
5214
  });
5053
5215
  const envelope = `${envelopeHeader}\n${itemHeaders}\n${item}`;
5054
- global$3.navigator.sendBeacon(url, envelope);
5216
+ try {
5217
+ sendReport(url, envelope);
5218
+ }
5219
+ catch (e) {
5220
+ logger.error(e);
5221
+ }
5055
5222
  }
5056
5223
  /**
5057
5224
  * Handle Sentry repsonse for promise-based transports.
@@ -5120,72 +5287,6 @@ var Sentry = (function (exports) {
5120
5287
  }
5121
5288
  }
5122
5289
 
5123
- /**
5124
- * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
5125
- * Whenever someone wraps the Fetch API and returns the wrong promise chain,
5126
- * this chain becomes orphaned and there is no possible way to capture it's rejections
5127
- * other than allowing it bubble up to this very handler. eg.
5128
- *
5129
- * const f = window.fetch;
5130
- * window.fetch = function () {
5131
- * const p = f.apply(this, arguments);
5132
- *
5133
- * p.then(function() {
5134
- * console.log('hi.');
5135
- * });
5136
- *
5137
- * return p;
5138
- * }
5139
- *
5140
- * `p.then(function () { ... })` is producing a completely separate promise chain,
5141
- * however, what's returned is `p` - the result of original `fetch` call.
5142
- *
5143
- * This mean, that whenever we use the Fetch API to send our own requests, _and_
5144
- * some ad-blocker blocks it, this orphaned chain will _always_ reject,
5145
- * effectively causing another event to be captured.
5146
- * This makes a whole process become an infinite loop, which we need to somehow
5147
- * deal with, and break it in one way or another.
5148
- *
5149
- * To deal with this issue, we are making sure that we _always_ use the real
5150
- * browser Fetch API, instead of relying on what `window.fetch` exposes.
5151
- * The only downside to this would be missing our own requests as breadcrumbs,
5152
- * but because we are already not doing this, it should be just fine.
5153
- *
5154
- * Possible failed fetch error messages per-browser:
5155
- *
5156
- * Chrome: Failed to fetch
5157
- * Edge: Failed to Fetch
5158
- * Firefox: NetworkError when attempting to fetch resource
5159
- * Safari: resource blocked by content blocker
5160
- */
5161
- function getNativeFetchImplementation() {
5162
- /* eslint-disable @typescript-eslint/unbound-method */
5163
- var _a, _b;
5164
- // Fast path to avoid DOM I/O
5165
- const global = getGlobalObject();
5166
- if (isNativeFetch(global.fetch)) {
5167
- return global.fetch.bind(global);
5168
- }
5169
- const document = global.document;
5170
- let fetchImpl = global.fetch;
5171
- // eslint-disable-next-line deprecation/deprecation
5172
- if (typeof ((_a = document) === null || _a === void 0 ? void 0 : _a.createElement) === `function`) {
5173
- try {
5174
- const sandbox = document.createElement('iframe');
5175
- sandbox.hidden = true;
5176
- document.head.appendChild(sandbox);
5177
- if ((_b = sandbox.contentWindow) === null || _b === void 0 ? void 0 : _b.fetch) {
5178
- fetchImpl = sandbox.contentWindow.fetch;
5179
- }
5180
- document.head.removeChild(sandbox);
5181
- }
5182
- catch (e) {
5183
- logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
5184
- }
5185
- }
5186
- return fetchImpl.bind(global);
5187
- /* eslint-enable @typescript-eslint/unbound-method */
5188
- }
5189
5290
  /** `fetch` based transport */
5190
5291
  class FetchTransport extends BaseTransport {
5191
5292
  constructor(options, fetchImpl = getNativeFetchImplementation()) {
@@ -5306,7 +5407,7 @@ var Sentry = (function (exports) {
5306
5407
  };
5307
5408
  request.open('POST', sentryRequest.url);
5308
5409
  for (const header in this.options.headers) {
5309
- if (this.options.headers.hasOwnProperty(header)) {
5410
+ if (Object.prototype.hasOwnProperty.call(this.options.headers, header)) {
5310
5411
  request.setRequestHeader(header, this.options.headers[header]);
5311
5412
  }
5312
5413
  }
@@ -5370,7 +5471,7 @@ var Sentry = (function (exports) {
5370
5471
  }
5371
5472
  }
5372
5473
 
5373
- const global$4 = getGlobalObject();
5474
+ const global$5 = getGlobalObject();
5374
5475
  let ignoreOnError = 0;
5375
5476
  /**
5376
5477
  * @hidden
@@ -5506,7 +5607,7 @@ var Sentry = (function (exports) {
5506
5607
  * @hidden
5507
5608
  */
5508
5609
  function injectReportDialog(options = {}) {
5509
- if (!global$4.document) {
5610
+ if (!global$5.document) {
5510
5611
  return;
5511
5612
  }
5512
5613
  if (!options.eventId) {
@@ -5517,14 +5618,14 @@ var Sentry = (function (exports) {
5517
5618
  logger.error(`Missing dsn option in showReportDialog call`);
5518
5619
  return;
5519
5620
  }
5520
- const script = global$4.document.createElement('script');
5621
+ const script = global$5.document.createElement('script');
5521
5622
  script.async = true;
5522
5623
  script.src = new API(options.dsn).getReportDialogEndpoint(options);
5523
5624
  if (options.onLoad) {
5524
5625
  // eslint-disable-next-line @typescript-eslint/unbound-method
5525
5626
  script.onload = options.onLoad;
5526
5627
  }
5527
- const injectionPoint = global$4.document.head || global$4.document.body;
5628
+ const injectionPoint = global$5.document.head || global$5.document.body;
5528
5629
  if (injectionPoint) {
5529
5630
  injectionPoint.appendChild(script);
5530
5631
  }
@@ -5826,7 +5927,7 @@ var Sentry = (function (exports) {
5826
5927
  const global = getGlobalObject();
5827
5928
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5828
5929
  const proto = global[target] && global[target].prototype;
5829
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5930
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
5830
5931
  if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
5831
5932
  return;
5832
5933
  }
@@ -6234,7 +6335,7 @@ var Sentry = (function (exports) {
6234
6335
  */
6235
6336
  LinkedErrors.id = 'LinkedErrors';
6236
6337
 
6237
- const global$5 = getGlobalObject();
6338
+ const global$6 = getGlobalObject();
6238
6339
  /** UserAgent */
6239
6340
  class UserAgent {
6240
6341
  constructor() {
@@ -6251,13 +6352,13 @@ var Sentry = (function (exports) {
6251
6352
  var _a, _b, _c;
6252
6353
  if (getCurrentHub().getIntegration(UserAgent)) {
6253
6354
  // if none of the information we want exists, don't bother
6254
- if (!global$5.navigator && !global$5.location && !global$5.document) {
6355
+ if (!global$6.navigator && !global$6.location && !global$6.document) {
6255
6356
  return event;
6256
6357
  }
6257
6358
  // grab as much info as exists and add it to the event
6258
- const url = ((_a = event.request) === null || _a === void 0 ? void 0 : _a.url) || ((_b = global$5.location) === null || _b === void 0 ? void 0 : _b.href);
6259
- const { referrer } = global$5.document || {};
6260
- const { userAgent } = global$5.navigator || {};
6359
+ 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);
6360
+ const { referrer } = global$6.document || {};
6361
+ const { userAgent } = global$6.navigator || {};
6261
6362
  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 }));
6262
6363
  const request = Object.assign(Object.assign({}, (url && { url })), { headers });
6263
6364
  return Object.assign(Object.assign({}, event), { request });