@sentry/browser 6.13.1 → 6.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/build/bundle.es6.js +453 -340
  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 +454 -342
  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 +1 -4
  11. package/dist/eventbuilder.js.map +1 -1
  12. package/dist/helpers.d.ts.map +1 -1
  13. package/dist/helpers.js +6 -2
  14. package/dist/helpers.js.map +1 -1
  15. package/dist/integrations/trycatch.js +1 -1
  16. package/dist/integrations/trycatch.js.map +1 -1
  17. package/dist/transports/base.d.ts.map +1 -1
  18. package/dist/transports/base.js +12 -9
  19. package/dist/transports/base.js.map +1 -1
  20. package/dist/transports/fetch.d.ts +1 -2
  21. package/dist/transports/fetch.d.ts.map +1 -1
  22. package/dist/transports/fetch.js +2 -67
  23. package/dist/transports/fetch.js.map +1 -1
  24. package/dist/transports/utils.d.ts +48 -0
  25. package/dist/transports/utils.d.ts.map +1 -0
  26. package/dist/transports/utils.js +99 -0
  27. package/dist/transports/utils.js.map +1 -0
  28. package/dist/transports/xhr.js +1 -1
  29. package/dist/transports/xhr.js.map +1 -1
  30. package/esm/eventbuilder.d.ts.map +1 -1
  31. package/esm/eventbuilder.js +1 -4
  32. package/esm/eventbuilder.js.map +1 -1
  33. package/esm/helpers.d.ts.map +1 -1
  34. package/esm/helpers.js +7 -3
  35. package/esm/helpers.js.map +1 -1
  36. package/esm/integrations/trycatch.js +1 -1
  37. package/esm/integrations/trycatch.js.map +1 -1
  38. package/esm/transports/base.d.ts.map +1 -1
  39. package/esm/transports/base.js +14 -11
  40. package/esm/transports/base.js.map +1 -1
  41. package/esm/transports/fetch.d.ts +1 -2
  42. package/esm/transports/fetch.d.ts.map +1 -1
  43. package/esm/transports/fetch.js +2 -67
  44. package/esm/transports/fetch.js.map +1 -1
  45. package/esm/transports/utils.d.ts +48 -0
  46. package/esm/transports/utils.d.ts.map +1 -0
  47. package/esm/transports/utils.js +96 -0
  48. package/esm/transports/utils.js.map +1 -0
  49. package/esm/transports/xhr.js +1 -1
  50. package/esm/transports/xhr.js.map +1 -1
  51. package/package.json +23 -23
@@ -1,4 +1,4 @@
1
- /*! @sentry/browser 6.13.1 (fdf519b) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.14.1 (687b6c4) | 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
  /**
@@ -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'
589
- ? window
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.
580
+ * @param callback The function to run against the original `console` messages
581
+ * @returns The results of the callback
598
582
  */
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
636
- */
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,79 +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
- try {
739
- return document.location.href;
740
- }
741
- catch (oO) {
742
- return '';
743
- }
744
- }
745
- const defaultRetryAfter = 60 * 1000; // 60 seconds
746
- /**
747
- * Extracts Retry-After value from the request header or returns default value
748
- * @param now current unix timestamp
749
- * @param header string representation of 'Retry-After' header
750
- */
751
- function parseRetryAfterHeader(now, header) {
752
- if (!header) {
753
- return defaultRetryAfter;
754
- }
755
- const headerDelay = parseInt(`${header}`, 10);
756
- if (!isNaN(headerDelay)) {
757
- return headerDelay * 1000;
758
- }
759
- const headerDate = Date.parse(`${header}`);
760
- if (!isNaN(headerDate)) {
761
- return headerDate - now;
762
- }
763
- return defaultRetryAfter;
764
- }
765
-
766
- /* eslint-disable @typescript-eslint/no-explicit-any */
767
- // TODO: Implement different loggers for different environments
768
- const global$1 = getGlobalObject();
769
- /** Prefix for logging strings */
770
- const PREFIX = 'Sentry Logger ';
771
608
  /** JSDoc */
772
609
  class Logger {
773
610
  /** JSDoc */
@@ -884,6 +721,61 @@ var Sentry = (function (exports) {
884
721
  }
885
722
  }
886
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
+
887
779
  /**
888
780
  * Replace a method in an object with a wrapped version of itself.
889
781
  *
@@ -1051,9 +943,13 @@ var Sentry = (function (exports) {
1051
943
  if (typeof global !== 'undefined' && value === global) {
1052
944
  return '[Global]';
1053
945
  }
946
+ // It's safe to use `window` and `document` here in this manner, as we are asserting using `typeof` first
947
+ // which won't throw if they are not present.
948
+ // eslint-disable-next-line no-restricted-globals
1054
949
  if (typeof window !== 'undefined' && value === window) {
1055
950
  return '[Window]';
1056
951
  }
952
+ // eslint-disable-next-line no-restricted-globals
1057
953
  if (typeof document !== 'undefined' && value === document) {
1058
954
  return '[Document]';
1059
955
  }
@@ -1783,18 +1679,191 @@ var Sentry = (function (exports) {
1783
1679
  return false;
1784
1680
  };
1785
1681
  }
1786
- let _oldOnUnhandledRejectionHandler = null;
1787
- /** JSDoc */
1788
- function instrumentUnhandledRejection() {
1789
- _oldOnUnhandledRejectionHandler = global$2.onunhandledrejection;
1790
- global$2.onunhandledrejection = function (e) {
1791
- triggerHandlers('unhandledrejection', e);
1792
- if (_oldOnUnhandledRejectionHandler) {
1793
- // eslint-disable-next-line prefer-rest-params
1794
- return _oldOnUnhandledRejectionHandler.apply(this, arguments);
1682
+ let _oldOnUnhandledRejectionHandler = null;
1683
+ /** JSDoc */
1684
+ function instrumentUnhandledRejection() {
1685
+ _oldOnUnhandledRejectionHandler = global$2.onunhandledrejection;
1686
+ global$2.onunhandledrejection = function (e) {
1687
+ triggerHandlers('unhandledrejection', e);
1688
+ if (_oldOnUnhandledRejectionHandler) {
1689
+ // eslint-disable-next-line prefer-rest-params
1690
+ return _oldOnUnhandledRejectionHandler.apply(this, arguments);
1691
+ }
1692
+ return true;
1693
+ };
1694
+ }
1695
+
1696
+ /**
1697
+ * UUID4 generator
1698
+ *
1699
+ * @returns string Generated UUID4.
1700
+ */
1701
+ function uuid4() {
1702
+ const global = getGlobalObject();
1703
+ const crypto = global.crypto || global.msCrypto;
1704
+ if (!(crypto === void 0) && crypto.getRandomValues) {
1705
+ // Use window.crypto API if available
1706
+ const arr = new Uint16Array(8);
1707
+ crypto.getRandomValues(arr);
1708
+ // set 4 in byte 7
1709
+ // eslint-disable-next-line no-bitwise
1710
+ arr[3] = (arr[3] & 0xfff) | 0x4000;
1711
+ // set 2 most significant bits of byte 9 to '10'
1712
+ // eslint-disable-next-line no-bitwise
1713
+ arr[4] = (arr[4] & 0x3fff) | 0x8000;
1714
+ const pad = (num) => {
1715
+ let v = num.toString(16);
1716
+ while (v.length < 4) {
1717
+ v = `0${v}`;
1718
+ }
1719
+ return v;
1720
+ };
1721
+ 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]));
1722
+ }
1723
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
1724
+ return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
1725
+ // eslint-disable-next-line no-bitwise
1726
+ const r = (Math.random() * 16) | 0;
1727
+ // eslint-disable-next-line no-bitwise
1728
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
1729
+ return v.toString(16);
1730
+ });
1731
+ }
1732
+ /**
1733
+ * Parses string form of URL into an object
1734
+ * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
1735
+ * // intentionally using regex and not <a/> href parsing trick because React Native and other
1736
+ * // environments where DOM might not be available
1737
+ * @returns parsed URL object
1738
+ */
1739
+ function parseUrl(url) {
1740
+ if (!url) {
1741
+ return {};
1742
+ }
1743
+ const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
1744
+ if (!match) {
1745
+ return {};
1746
+ }
1747
+ // coerce to undefined values to empty string so we don't get 'undefined'
1748
+ const query = match[6] || '';
1749
+ const fragment = match[8] || '';
1750
+ return {
1751
+ host: match[4],
1752
+ path: match[5],
1753
+ protocol: match[2],
1754
+ relative: match[5] + query + fragment,
1755
+ };
1756
+ }
1757
+ /**
1758
+ * Extracts either message or type+value from an event that can be used for user-facing logs
1759
+ * @returns event's description
1760
+ */
1761
+ function getEventDescription(event) {
1762
+ if (event.message) {
1763
+ return event.message;
1764
+ }
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}`;
1795
1769
  }
1770
+ return exception.type || exception.value || event.event_id || '<unknown>';
1771
+ }
1772
+ return event.event_id || '<unknown>';
1773
+ }
1774
+ /**
1775
+ * Adds exception values, type and value to an synthetic Exception.
1776
+ * @param event The event to modify.
1777
+ * @param value Value of the exception.
1778
+ * @param type Type of the exception.
1779
+ * @hidden
1780
+ */
1781
+ 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';
1787
+ }
1788
+ /**
1789
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
1790
+ *
1791
+ * @param event The event to modify.
1792
+ * @param newMechanism Mechanism data to add to the event.
1793
+ * @hidden
1794
+ */
1795
+ function addExceptionMechanism(event, newMechanism) {
1796
+ var _a;
1797
+ if (!event.exception || !event.exception.values) {
1798
+ return;
1799
+ }
1800
+ const exceptionValue0 = event.exception.values[0];
1801
+ const defaultMechanism = { type: 'generic', handled: true };
1802
+ const currentMechanism = exceptionValue0.mechanism;
1803
+ exceptionValue0.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
1804
+ 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;
1807
+ }
1808
+ }
1809
+ const defaultRetryAfter = 60 * 1000; // 60 seconds
1810
+ /**
1811
+ * Extracts Retry-After value from the request header or returns default value
1812
+ * @param now current unix timestamp
1813
+ * @param header string representation of 'Retry-After' header
1814
+ */
1815
+ function parseRetryAfterHeader(now, header) {
1816
+ if (!header) {
1817
+ return defaultRetryAfter;
1818
+ }
1819
+ const headerDelay = parseInt(`${header}`, 10);
1820
+ if (!isNaN(headerDelay)) {
1821
+ return headerDelay * 1000;
1822
+ }
1823
+ const headerDate = Date.parse(`${header}`);
1824
+ if (!isNaN(headerDate)) {
1825
+ return headerDate - now;
1826
+ }
1827
+ return defaultRetryAfter;
1828
+ }
1829
+ /**
1830
+ * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
1831
+ * in question), and marks it captured if not.
1832
+ *
1833
+ * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
1834
+ * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
1835
+ * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
1836
+ * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
1837
+ * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
1838
+ * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
1839
+ * see it.
1840
+ *
1841
+ * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
1842
+ * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
1843
+ * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
1844
+ * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
1845
+ * must be done before the exception captured.
1846
+ *
1847
+ * @param A thrown exception to check or flag as having been seen
1848
+ * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
1849
+ */
1850
+ function checkOrSetAlreadyCaught(exception) {
1851
+ var _a;
1852
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1853
+ if ((_a = exception) === null || _a === void 0 ? void 0 : _a.__sentry_captured__) {
1796
1854
  return true;
1797
- };
1855
+ }
1856
+ try {
1857
+ // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
1858
+ // `ExtraErrorData` integration
1859
+ Object.defineProperty(exception, '__sentry_captured__', {
1860
+ value: true,
1861
+ });
1862
+ }
1863
+ catch (err) {
1864
+ // `exception` is a primitive, so we can't mark it seen
1865
+ }
1866
+ return false;
1798
1867
  }
1799
1868
 
1800
1869
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
@@ -3602,6 +3671,7 @@ var Sentry = (function (exports) {
3602
3671
  }
3603
3672
 
3604
3673
  /* eslint-disable max-lines */
3674
+ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
3605
3675
  /**
3606
3676
  * Base implementation for all JavaScript SDK clients.
3607
3677
  *
@@ -3657,6 +3727,11 @@ var Sentry = (function (exports) {
3657
3727
  */
3658
3728
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
3659
3729
  captureException(exception, hint, scope) {
3730
+ // ensure we haven't captured this very object before
3731
+ if (checkOrSetAlreadyCaught(exception)) {
3732
+ logger.log(ALREADY_SEEN_ERROR);
3733
+ return;
3734
+ }
3660
3735
  let eventId = hint && hint.event_id;
3661
3736
  this._process(this._getBackend()
3662
3737
  .eventFromException(exception, hint)
@@ -3685,6 +3760,12 @@ var Sentry = (function (exports) {
3685
3760
  * @inheritDoc
3686
3761
  */
3687
3762
  captureEvent(event, hint, scope) {
3763
+ var _a;
3764
+ // ensure we haven't captured this very object before
3765
+ if (((_a = hint) === null || _a === void 0 ? void 0 : _a.originalException) && checkOrSetAlreadyCaught(hint.originalException)) {
3766
+ logger.log(ALREADY_SEEN_ERROR);
3767
+ return;
3768
+ }
3688
3769
  let eventId = hint && hint.event_id;
3689
3770
  this._process(this._captureEvent(event, hint, scope).then(result => {
3690
3771
  eventId = result;
@@ -4280,7 +4361,7 @@ var Sentry = (function (exports) {
4280
4361
  hub.bindClient(client);
4281
4362
  }
4282
4363
 
4283
- const SDK_VERSION = '6.13.1';
4364
+ const SDK_VERSION = '6.14.1';
4284
4365
 
4285
4366
  let originalFunctionToString;
4286
4367
  /** Patch toString calls to return proper name for wrapped functions */
@@ -4851,10 +4932,7 @@ var Sentry = (function (exports) {
4851
4932
  const event = eventFromUnknownInput(exception, syntheticException, {
4852
4933
  attachStacktrace: options.attachStacktrace,
4853
4934
  });
4854
- addExceptionMechanism(event, {
4855
- handled: true,
4856
- type: 'generic',
4857
- });
4935
+ addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
4858
4936
  event.level = exports.Severity.Error;
4859
4937
  if (hint && hint.event_id) {
4860
4938
  event.event_id = hint.event_id;
@@ -4953,12 +5031,108 @@ var Sentry = (function (exports) {
4953
5031
  return event;
4954
5032
  }
4955
5033
 
5034
+ const global$3 = getGlobalObject();
5035
+ let cachedFetchImpl;
5036
+ /**
5037
+ * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
5038
+ * Whenever someone wraps the Fetch API and returns the wrong promise chain,
5039
+ * this chain becomes orphaned and there is no possible way to capture it's rejections
5040
+ * other than allowing it bubble up to this very handler. eg.
5041
+ *
5042
+ * const f = window.fetch;
5043
+ * window.fetch = function () {
5044
+ * const p = f.apply(this, arguments);
5045
+ *
5046
+ * p.then(function() {
5047
+ * console.log('hi.');
5048
+ * });
5049
+ *
5050
+ * return p;
5051
+ * }
5052
+ *
5053
+ * `p.then(function () { ... })` is producing a completely separate promise chain,
5054
+ * however, what's returned is `p` - the result of original `fetch` call.
5055
+ *
5056
+ * This mean, that whenever we use the Fetch API to send our own requests, _and_
5057
+ * some ad-blocker blocks it, this orphaned chain will _always_ reject,
5058
+ * effectively causing another event to be captured.
5059
+ * This makes a whole process become an infinite loop, which we need to somehow
5060
+ * deal with, and break it in one way or another.
5061
+ *
5062
+ * To deal with this issue, we are making sure that we _always_ use the real
5063
+ * browser Fetch API, instead of relying on what `window.fetch` exposes.
5064
+ * The only downside to this would be missing our own requests as breadcrumbs,
5065
+ * but because we are already not doing this, it should be just fine.
5066
+ *
5067
+ * Possible failed fetch error messages per-browser:
5068
+ *
5069
+ * Chrome: Failed to fetch
5070
+ * Edge: Failed to Fetch
5071
+ * Firefox: NetworkError when attempting to fetch resource
5072
+ * Safari: resource blocked by content blocker
5073
+ */
5074
+ function getNativeFetchImplementation() {
5075
+ var _a, _b;
5076
+ if (cachedFetchImpl) {
5077
+ return cachedFetchImpl;
5078
+ }
5079
+ /* eslint-disable @typescript-eslint/unbound-method */
5080
+ // Fast path to avoid DOM I/O
5081
+ if (isNativeFetch(global$3.fetch)) {
5082
+ return (cachedFetchImpl = global$3.fetch.bind(global$3));
5083
+ }
5084
+ const document = global$3.document;
5085
+ let fetchImpl = global$3.fetch;
5086
+ // eslint-disable-next-line deprecation/deprecation
5087
+ if (typeof ((_a = document) === null || _a === void 0 ? void 0 : _a.createElement) === `function`) {
5088
+ try {
5089
+ const sandbox = document.createElement('iframe');
5090
+ sandbox.hidden = true;
5091
+ document.head.appendChild(sandbox);
5092
+ if ((_b = sandbox.contentWindow) === null || _b === void 0 ? void 0 : _b.fetch) {
5093
+ fetchImpl = sandbox.contentWindow.fetch;
5094
+ }
5095
+ document.head.removeChild(sandbox);
5096
+ }
5097
+ catch (e) {
5098
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
5099
+ }
5100
+ }
5101
+ return (cachedFetchImpl = fetchImpl.bind(global$3));
5102
+ /* eslint-enable @typescript-eslint/unbound-method */
5103
+ }
5104
+ /**
5105
+ * Sends sdk client report using sendBeacon or fetch as a fallback if available
5106
+ *
5107
+ * @param url report endpoint
5108
+ * @param body report payload
5109
+ */
5110
+ function sendReport(url, body) {
5111
+ const isRealNavigator = Object.prototype.toString.call(global$3 && global$3.navigator) === '[object Navigator]';
5112
+ const hasSendBeacon = isRealNavigator && typeof global$3.navigator.sendBeacon === 'function';
5113
+ if (hasSendBeacon) {
5114
+ // Prevent illegal invocations - https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
5115
+ const sendBeacon = global$3.navigator.sendBeacon.bind(global$3.navigator);
5116
+ return sendBeacon(url, body);
5117
+ }
5118
+ if (supportsFetch()) {
5119
+ const fetch = getNativeFetchImplementation();
5120
+ return forget(fetch(url, {
5121
+ body,
5122
+ method: 'POST',
5123
+ credentials: 'omit',
5124
+ keepalive: true,
5125
+ }));
5126
+ }
5127
+ }
5128
+
4956
5129
  const CATEGORY_MAPPING = {
4957
5130
  event: 'error',
4958
5131
  transaction: 'transaction',
4959
5132
  session: 'session',
4960
5133
  attachment: 'attachment',
4961
5134
  };
5135
+ const global$4 = getGlobalObject();
4962
5136
  /** Base Transport class implementation */
4963
5137
  class BaseTransport {
4964
5138
  constructor(options) {
@@ -4971,9 +5145,9 @@ var Sentry = (function (exports) {
4971
5145
  this._api = new API(options.dsn, options._metadata, options.tunnel);
4972
5146
  // eslint-disable-next-line deprecation/deprecation
4973
5147
  this.url = this._api.getStoreEndpointWithUrlEncodedAuth();
4974
- if (this.options.sendClientReports && document) {
4975
- document.addEventListener('visibilitychange', () => {
4976
- if (document.visibilityState === 'hidden') {
5148
+ if (this.options.sendClientReports && global$4.document) {
5149
+ global$4.document.addEventListener('visibilitychange', () => {
5150
+ if (global$4.document.visibilityState === 'hidden') {
4977
5151
  this._flushOutcomes();
4978
5152
  }
4979
5153
  });
@@ -5015,10 +5189,6 @@ var Sentry = (function (exports) {
5015
5189
  if (!this.options.sendClientReports) {
5016
5190
  return;
5017
5191
  }
5018
- if (!navigator || typeof navigator.sendBeacon !== 'function') {
5019
- logger.warn('Beacon API not available, skipping sending outcomes.');
5020
- return;
5021
- }
5022
5192
  const outcomes = this._outcomes;
5023
5193
  this._outcomes = {};
5024
5194
  // Nothing to send
@@ -5029,7 +5199,7 @@ var Sentry = (function (exports) {
5029
5199
  logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
5030
5200
  const url = this._api.getEnvelopeEndpointWithUrlEncodedAuth();
5031
5201
  // Envelope header is required to be at least an empty object
5032
- const envelopeHeader = JSON.stringify({});
5202
+ const envelopeHeader = JSON.stringify(Object.assign({}, (this.options.tunnel && { dsn: this._api.getDsn().toString() })));
5033
5203
  const itemHeaders = JSON.stringify({
5034
5204
  type: 'client_report',
5035
5205
  });
@@ -5045,7 +5215,12 @@ var Sentry = (function (exports) {
5045
5215
  }),
5046
5216
  });
5047
5217
  const envelope = `${envelopeHeader}\n${itemHeaders}\n${item}`;
5048
- navigator.sendBeacon(url, envelope);
5218
+ try {
5219
+ sendReport(url, envelope);
5220
+ }
5221
+ catch (e) {
5222
+ logger.error(e);
5223
+ }
5049
5224
  }
5050
5225
  /**
5051
5226
  * Handle Sentry repsonse for promise-based transports.
@@ -5114,72 +5289,6 @@ var Sentry = (function (exports) {
5114
5289
  }
5115
5290
  }
5116
5291
 
5117
- /**
5118
- * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
5119
- * Whenever someone wraps the Fetch API and returns the wrong promise chain,
5120
- * this chain becomes orphaned and there is no possible way to capture it's rejections
5121
- * other than allowing it bubble up to this very handler. eg.
5122
- *
5123
- * const f = window.fetch;
5124
- * window.fetch = function () {
5125
- * const p = f.apply(this, arguments);
5126
- *
5127
- * p.then(function() {
5128
- * console.log('hi.');
5129
- * });
5130
- *
5131
- * return p;
5132
- * }
5133
- *
5134
- * `p.then(function () { ... })` is producing a completely separate promise chain,
5135
- * however, what's returned is `p` - the result of original `fetch` call.
5136
- *
5137
- * This mean, that whenever we use the Fetch API to send our own requests, _and_
5138
- * some ad-blocker blocks it, this orphaned chain will _always_ reject,
5139
- * effectively causing another event to be captured.
5140
- * This makes a whole process become an infinite loop, which we need to somehow
5141
- * deal with, and break it in one way or another.
5142
- *
5143
- * To deal with this issue, we are making sure that we _always_ use the real
5144
- * browser Fetch API, instead of relying on what `window.fetch` exposes.
5145
- * The only downside to this would be missing our own requests as breadcrumbs,
5146
- * but because we are already not doing this, it should be just fine.
5147
- *
5148
- * Possible failed fetch error messages per-browser:
5149
- *
5150
- * Chrome: Failed to fetch
5151
- * Edge: Failed to Fetch
5152
- * Firefox: NetworkError when attempting to fetch resource
5153
- * Safari: resource blocked by content blocker
5154
- */
5155
- function getNativeFetchImplementation() {
5156
- /* eslint-disable @typescript-eslint/unbound-method */
5157
- var _a, _b;
5158
- // Fast path to avoid DOM I/O
5159
- const global = getGlobalObject();
5160
- if (isNativeFetch(global.fetch)) {
5161
- return global.fetch.bind(global);
5162
- }
5163
- const document = global.document;
5164
- let fetchImpl = global.fetch;
5165
- // eslint-disable-next-line deprecation/deprecation
5166
- if (typeof ((_a = document) === null || _a === void 0 ? void 0 : _a.createElement) === `function`) {
5167
- try {
5168
- const sandbox = document.createElement('iframe');
5169
- sandbox.hidden = true;
5170
- document.head.appendChild(sandbox);
5171
- if ((_b = sandbox.contentWindow) === null || _b === void 0 ? void 0 : _b.fetch) {
5172
- fetchImpl = sandbox.contentWindow.fetch;
5173
- }
5174
- document.head.removeChild(sandbox);
5175
- }
5176
- catch (e) {
5177
- logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
5178
- }
5179
- }
5180
- return fetchImpl.bind(global);
5181
- /* eslint-enable @typescript-eslint/unbound-method */
5182
- }
5183
5292
  /** `fetch` based transport */
5184
5293
  class FetchTransport extends BaseTransport {
5185
5294
  constructor(options, fetchImpl = getNativeFetchImplementation()) {
@@ -5300,7 +5409,7 @@ var Sentry = (function (exports) {
5300
5409
  };
5301
5410
  request.open('POST', sentryRequest.url);
5302
5411
  for (const header in this.options.headers) {
5303
- if (this.options.headers.hasOwnProperty(header)) {
5412
+ if (Object.prototype.hasOwnProperty.call(this.options.headers, header)) {
5304
5413
  request.setRequestHeader(header, this.options.headers[header]);
5305
5414
  }
5306
5415
  }
@@ -5364,6 +5473,7 @@ var Sentry = (function (exports) {
5364
5473
  }
5365
5474
  }
5366
5475
 
5476
+ const global$5 = getGlobalObject();
5367
5477
  let ignoreOnError = 0;
5368
5478
  /**
5369
5479
  * @hidden
@@ -5499,6 +5609,9 @@ var Sentry = (function (exports) {
5499
5609
  * @hidden
5500
5610
  */
5501
5611
  function injectReportDialog(options = {}) {
5612
+ if (!global$5.document) {
5613
+ return;
5614
+ }
5502
5615
  if (!options.eventId) {
5503
5616
  logger.error(`Missing eventId option in showReportDialog call`);
5504
5617
  return;
@@ -5507,14 +5620,14 @@ var Sentry = (function (exports) {
5507
5620
  logger.error(`Missing dsn option in showReportDialog call`);
5508
5621
  return;
5509
5622
  }
5510
- const script = document.createElement('script');
5623
+ const script = global$5.document.createElement('script');
5511
5624
  script.async = true;
5512
5625
  script.src = new API(options.dsn).getReportDialogEndpoint(options);
5513
5626
  if (options.onLoad) {
5514
5627
  // eslint-disable-next-line @typescript-eslint/unbound-method
5515
5628
  script.onload = options.onLoad;
5516
5629
  }
5517
- const injectionPoint = document.head || document.body;
5630
+ const injectionPoint = global$5.document.head || global$5.document.body;
5518
5631
  if (injectionPoint) {
5519
5632
  injectionPoint.appendChild(script);
5520
5633
  }
@@ -5816,7 +5929,7 @@ var Sentry = (function (exports) {
5816
5929
  const global = getGlobalObject();
5817
5930
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5818
5931
  const proto = global[target] && global[target].prototype;
5819
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5932
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
5820
5933
  if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
5821
5934
  return;
5822
5935
  }
@@ -6224,7 +6337,7 @@ var Sentry = (function (exports) {
6224
6337
  */
6225
6338
  LinkedErrors.id = 'LinkedErrors';
6226
6339
 
6227
- const global$3 = getGlobalObject();
6340
+ const global$6 = getGlobalObject();
6228
6341
  /** UserAgent */
6229
6342
  class UserAgent {
6230
6343
  constructor() {
@@ -6241,13 +6354,13 @@ var Sentry = (function (exports) {
6241
6354
  var _a, _b, _c;
6242
6355
  if (getCurrentHub().getIntegration(UserAgent)) {
6243
6356
  // if none of the information we want exists, don't bother
6244
- if (!global$3.navigator && !global$3.location && !global$3.document) {
6357
+ if (!global$6.navigator && !global$6.location && !global$6.document) {
6245
6358
  return event;
6246
6359
  }
6247
6360
  // grab as much info as exists and add it to the event
6248
- const url = ((_a = event.request) === null || _a === void 0 ? void 0 : _a.url) || ((_b = global$3.location) === null || _b === void 0 ? void 0 : _b.href);
6249
- const { referrer } = global$3.document || {};
6250
- const { userAgent } = global$3.navigator || {};
6361
+ 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);
6362
+ const { referrer } = global$6.document || {};
6363
+ const { userAgent } = global$6.navigator || {};
6251
6364
  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 }));
6252
6365
  const request = Object.assign(Object.assign({}, (url && { url })), { headers });
6253
6366
  return Object.assign(Object.assign({}, event), { request });