@sentry/browser 6.13.3 → 6.14.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.
@@ -1,4 +1,4 @@
1
- /*! @sentry/browser 6.13.3 (cbb01ba) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.14.0 (574741b) | https://github.com/getsentry/sentry-javascript */
2
2
  var Sentry = (function (exports) {
3
3
  /** Console logging verbosity for the SDK. */
4
4
  var LogLevel;
@@ -157,6 +157,49 @@ var Sentry = (function (exports) {
157
157
  });
158
158
  }
159
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
+
160
203
  /* eslint-disable @typescript-eslint/no-explicit-any */
161
204
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
162
205
  /**
@@ -392,6 +435,18 @@ var Sentry = (function (exports) {
392
435
  }
393
436
  }
394
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
+ }
395
450
  }
396
451
 
397
452
  const setPrototypeOf = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties);
@@ -515,174 +570,17 @@ var Sentry = (function (exports) {
515
570
  }
516
571
  }
517
572
 
573
+ // TODO: Implement different loggers for different environments
574
+ const global$1 = getGlobalObject();
575
+ /** Prefix for logging strings */
576
+ const PREFIX = 'Sentry Logger ';
518
577
  /**
519
- * Checks whether we're in the Node.js or Browser environment
520
- *
521
- * @returns Answer to given question
522
- */
523
- function isNodeEnv() {
524
- return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
525
- }
526
- /**
527
- * Requires a module which is protected against bundler minification.
528
- *
529
- * @param request The module path to resolve
530
- */
531
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
532
- function dynamicRequire(mod, request) {
533
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
534
- return mod.require(request);
535
- }
536
-
537
- /**
538
- * Truncates given string to the maximum characters count
539
- *
540
- * @param str An object that contains serializable values
541
- * @param max Maximum number of characters in truncated string (0 = unlimited)
542
- * @returns string Encoded
543
- */
544
- function truncate(str, max = 0) {
545
- if (typeof str !== 'string' || max === 0) {
546
- return str;
547
- }
548
- return str.length <= max ? str : `${str.substr(0, max)}...`;
549
- }
550
- /**
551
- * Join values in array
552
- * @param input array of values to be joined together
553
- * @param delimiter string to be placed in-between values
554
- * @returns Joined values
555
- */
556
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
557
- function safeJoin(input, delimiter) {
558
- if (!Array.isArray(input)) {
559
- return '';
560
- }
561
- const output = [];
562
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
563
- for (let i = 0; i < input.length; i++) {
564
- const value = input[i];
565
- try {
566
- output.push(String(value));
567
- }
568
- catch (e) {
569
- output.push('[value cannot be serialized]');
570
- }
571
- }
572
- return output.join(delimiter);
573
- }
574
- /**
575
- * Checks if the value matches a regex or includes the string
576
- * @param value The string value to be checked against
577
- * @param pattern Either a regex or a string that must be contained in value
578
- */
579
- function isMatchingPattern(value, pattern) {
580
- if (!isString(value)) {
581
- return false;
582
- }
583
- if (isRegExp(pattern)) {
584
- return pattern.test(value);
585
- }
586
- if (typeof pattern === 'string') {
587
- return value.indexOf(pattern) !== -1;
588
- }
589
- return false;
590
- }
591
-
592
- const fallbackGlobalObject = {};
593
- /**
594
- * Safely get global scope object
595
- *
596
- * @returns Global scope object
597
- */
598
- function getGlobalObject() {
599
- return (isNodeEnv()
600
- ? global
601
- : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
602
- ? window // eslint-disable-line no-restricted-globals
603
- : typeof self !== 'undefined'
604
- ? self
605
- : fallbackGlobalObject);
606
- }
607
- /**
608
- * UUID4 generator
578
+ * Temporarily unwrap `console.log` and friends in order to perform the given callback using the original methods.
579
+ * Restores wrapping after the callback completes.
609
580
  *
610
- * @returns string Generated UUID4.
581
+ * @param callback The function to run against the original `console` messages
582
+ * @returns The results of the callback
611
583
  */
612
- function uuid4() {
613
- const global = getGlobalObject();
614
- const crypto = global.crypto || global.msCrypto;
615
- if (!(crypto === void 0) && crypto.getRandomValues) {
616
- // Use window.crypto API if available
617
- const arr = new Uint16Array(8);
618
- crypto.getRandomValues(arr);
619
- // set 4 in byte 7
620
- // eslint-disable-next-line no-bitwise
621
- arr[3] = (arr[3] & 0xfff) | 0x4000;
622
- // set 2 most significant bits of byte 9 to '10'
623
- // eslint-disable-next-line no-bitwise
624
- arr[4] = (arr[4] & 0x3fff) | 0x8000;
625
- const pad = (num) => {
626
- let v = num.toString(16);
627
- while (v.length < 4) {
628
- v = `0${v}`;
629
- }
630
- return v;
631
- };
632
- 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]));
633
- }
634
- // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
635
- return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
636
- // eslint-disable-next-line no-bitwise
637
- const r = (Math.random() * 16) | 0;
638
- // eslint-disable-next-line no-bitwise
639
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
640
- return v.toString(16);
641
- });
642
- }
643
- /**
644
- * Parses string form of URL into an object
645
- * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
646
- * // intentionally using regex and not <a/> href parsing trick because React Native and other
647
- * // environments where DOM might not be available
648
- * @returns parsed URL object
649
- */
650
- function parseUrl(url) {
651
- if (!url) {
652
- return {};
653
- }
654
- const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
655
- if (!match) {
656
- return {};
657
- }
658
- // coerce to undefined values to empty string so we don't get 'undefined'
659
- const query = match[6] || '';
660
- const fragment = match[8] || '';
661
- return {
662
- host: match[4],
663
- path: match[5],
664
- protocol: match[2],
665
- relative: match[5] + query + fragment,
666
- };
667
- }
668
- /**
669
- * Extracts either message or type+value from an event that can be used for user-facing logs
670
- * @returns event's description
671
- */
672
- function getEventDescription(event) {
673
- if (event.message) {
674
- return event.message;
675
- }
676
- if (event.exception && event.exception.values && event.exception.values[0]) {
677
- const exception = event.exception.values[0];
678
- if (exception.type && exception.value) {
679
- return `${exception.type}: ${exception.value}`;
680
- }
681
- return exception.type || exception.value || event.event_id || '<unknown>';
682
- }
683
- return event.event_id || '<unknown>';
684
- }
685
- /** JSDoc */
686
584
  function consoleSandbox(callback) {
687
585
  const global = getGlobalObject();
688
586
  const levels = ['debug', 'info', 'warn', 'error', 'log', 'assert'];
@@ -708,80 +606,6 @@ var Sentry = (function (exports) {
708
606
  });
709
607
  return result;
710
608
  }
711
- /**
712
- * Adds exception values, type and value to an synthetic Exception.
713
- * @param event The event to modify.
714
- * @param value Value of the exception.
715
- * @param type Type of the exception.
716
- * @hidden
717
- */
718
- function addExceptionTypeValue(event, value, type) {
719
- event.exception = event.exception || {};
720
- event.exception.values = event.exception.values || [];
721
- event.exception.values[0] = event.exception.values[0] || {};
722
- event.exception.values[0].value = event.exception.values[0].value || value || '';
723
- event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
724
- }
725
- /**
726
- * Adds exception mechanism to a given event.
727
- * @param event The event to modify.
728
- * @param mechanism Mechanism of the mechanism.
729
- * @hidden
730
- */
731
- function addExceptionMechanism(event, mechanism = {}) {
732
- // TODO: Use real type with `keyof Mechanism` thingy and maybe make it better?
733
- try {
734
- // @ts-ignore Type 'Mechanism | {}' is not assignable to type 'Mechanism | undefined'
735
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
736
- event.exception.values[0].mechanism = event.exception.values[0].mechanism || {};
737
- Object.keys(mechanism).forEach(key => {
738
- // @ts-ignore Mechanism has no index signature
739
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
740
- event.exception.values[0].mechanism[key] = mechanism[key];
741
- });
742
- }
743
- catch (_oO) {
744
- // no-empty
745
- }
746
- }
747
- /**
748
- * A safe form of location.href
749
- */
750
- function getLocationHref() {
751
- const global = getGlobalObject();
752
- try {
753
- return global.document.location.href;
754
- }
755
- catch (oO) {
756
- return '';
757
- }
758
- }
759
- const defaultRetryAfter = 60 * 1000; // 60 seconds
760
- /**
761
- * Extracts Retry-After value from the request header or returns default value
762
- * @param now current unix timestamp
763
- * @param header string representation of 'Retry-After' header
764
- */
765
- function parseRetryAfterHeader(now, header) {
766
- if (!header) {
767
- return defaultRetryAfter;
768
- }
769
- const headerDelay = parseInt(`${header}`, 10);
770
- if (!isNaN(headerDelay)) {
771
- return headerDelay * 1000;
772
- }
773
- const headerDate = Date.parse(`${header}`);
774
- if (!isNaN(headerDate)) {
775
- return headerDate - now;
776
- }
777
- return defaultRetryAfter;
778
- }
779
-
780
- /* eslint-disable @typescript-eslint/no-explicit-any */
781
- // TODO: Implement different loggers for different environments
782
- const global$1 = getGlobalObject();
783
- /** Prefix for logging strings */
784
- const PREFIX = 'Sentry Logger ';
785
609
  /** JSDoc */
786
610
  class Logger {
787
611
  /** JSDoc */
@@ -898,6 +722,61 @@ var Sentry = (function (exports) {
898
722
  }
899
723
  }
900
724
 
725
+ /**
726
+ * Truncates given string to the maximum characters count
727
+ *
728
+ * @param str An object that contains serializable values
729
+ * @param max Maximum number of characters in truncated string (0 = unlimited)
730
+ * @returns string Encoded
731
+ */
732
+ function truncate(str, max = 0) {
733
+ if (typeof str !== 'string' || max === 0) {
734
+ return str;
735
+ }
736
+ return str.length <= max ? str : `${str.substr(0, max)}...`;
737
+ }
738
+ /**
739
+ * Join values in array
740
+ * @param input array of values to be joined together
741
+ * @param delimiter string to be placed in-between values
742
+ * @returns Joined values
743
+ */
744
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
745
+ function safeJoin(input, delimiter) {
746
+ if (!Array.isArray(input)) {
747
+ return '';
748
+ }
749
+ const output = [];
750
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
751
+ for (let i = 0; i < input.length; i++) {
752
+ const value = input[i];
753
+ try {
754
+ output.push(String(value));
755
+ }
756
+ catch (e) {
757
+ output.push('[value cannot be serialized]');
758
+ }
759
+ }
760
+ return output.join(delimiter);
761
+ }
762
+ /**
763
+ * Checks if the value matches a regex or includes the string
764
+ * @param value The string value to be checked against
765
+ * @param pattern Either a regex or a string that must be contained in value
766
+ */
767
+ function isMatchingPattern(value, pattern) {
768
+ if (!isString(value)) {
769
+ return false;
770
+ }
771
+ if (isRegExp(pattern)) {
772
+ return pattern.test(value);
773
+ }
774
+ if (typeof pattern === 'string') {
775
+ return value.indexOf(pattern) !== -1;
776
+ }
777
+ return false;
778
+ }
779
+
901
780
  /**
902
781
  * Replace a method in an object with a wrapped version of itself.
903
782
  *
@@ -1815,6 +1694,179 @@ var Sentry = (function (exports) {
1815
1694
  };
1816
1695
  }
1817
1696
 
1697
+ /**
1698
+ * UUID4 generator
1699
+ *
1700
+ * @returns string Generated UUID4.
1701
+ */
1702
+ function uuid4() {
1703
+ const global = getGlobalObject();
1704
+ const crypto = global.crypto || global.msCrypto;
1705
+ if (!(crypto === void 0) && crypto.getRandomValues) {
1706
+ // Use window.crypto API if available
1707
+ const arr = new Uint16Array(8);
1708
+ crypto.getRandomValues(arr);
1709
+ // set 4 in byte 7
1710
+ // eslint-disable-next-line no-bitwise
1711
+ arr[3] = (arr[3] & 0xfff) | 0x4000;
1712
+ // set 2 most significant bits of byte 9 to '10'
1713
+ // eslint-disable-next-line no-bitwise
1714
+ arr[4] = (arr[4] & 0x3fff) | 0x8000;
1715
+ const pad = (num) => {
1716
+ let v = num.toString(16);
1717
+ while (v.length < 4) {
1718
+ v = `0${v}`;
1719
+ }
1720
+ return v;
1721
+ };
1722
+ 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]));
1723
+ }
1724
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
1725
+ return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
1726
+ // eslint-disable-next-line no-bitwise
1727
+ const r = (Math.random() * 16) | 0;
1728
+ // eslint-disable-next-line no-bitwise
1729
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
1730
+ return v.toString(16);
1731
+ });
1732
+ }
1733
+ /**
1734
+ * Parses string form of URL into an object
1735
+ * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
1736
+ * // intentionally using regex and not <a/> href parsing trick because React Native and other
1737
+ * // environments where DOM might not be available
1738
+ * @returns parsed URL object
1739
+ */
1740
+ function parseUrl(url) {
1741
+ if (!url) {
1742
+ return {};
1743
+ }
1744
+ const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
1745
+ if (!match) {
1746
+ return {};
1747
+ }
1748
+ // coerce to undefined values to empty string so we don't get 'undefined'
1749
+ const query = match[6] || '';
1750
+ const fragment = match[8] || '';
1751
+ return {
1752
+ host: match[4],
1753
+ path: match[5],
1754
+ protocol: match[2],
1755
+ relative: match[5] + query + fragment,
1756
+ };
1757
+ }
1758
+ /**
1759
+ * Extracts either message or type+value from an event that can be used for user-facing logs
1760
+ * @returns event's description
1761
+ */
1762
+ function getEventDescription(event) {
1763
+ if (event.message) {
1764
+ return event.message;
1765
+ }
1766
+ if (event.exception && event.exception.values && event.exception.values[0]) {
1767
+ const exception = event.exception.values[0];
1768
+ if (exception.type && exception.value) {
1769
+ return `${exception.type}: ${exception.value}`;
1770
+ }
1771
+ return exception.type || exception.value || event.event_id || '<unknown>';
1772
+ }
1773
+ return event.event_id || '<unknown>';
1774
+ }
1775
+ /**
1776
+ * Adds exception values, type and value to an synthetic Exception.
1777
+ * @param event The event to modify.
1778
+ * @param value Value of the exception.
1779
+ * @param type Type of the exception.
1780
+ * @hidden
1781
+ */
1782
+ function addExceptionTypeValue(event, value, type) {
1783
+ event.exception = event.exception || {};
1784
+ event.exception.values = event.exception.values || [];
1785
+ event.exception.values[0] = event.exception.values[0] || {};
1786
+ event.exception.values[0].value = event.exception.values[0].value || value || '';
1787
+ event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
1788
+ }
1789
+ /**
1790
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
1791
+ *
1792
+ * @param event The event to modify.
1793
+ * @param newMechanism Mechanism data to add to the event.
1794
+ * @hidden
1795
+ */
1796
+ function addExceptionMechanism(event, newMechanism) {
1797
+ var _a;
1798
+ if (!event.exception || !event.exception.values) {
1799
+ return;
1800
+ }
1801
+ const exceptionValue0 = event.exception.values[0];
1802
+ const defaultMechanism = { type: 'generic', handled: true };
1803
+ const currentMechanism = exceptionValue0.mechanism;
1804
+ exceptionValue0.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
1805
+ if (newMechanism && 'data' in newMechanism) {
1806
+ const mergedData = Object.assign(Object.assign({}, (_a = currentMechanism) === null || _a === void 0 ? void 0 : _a.data), newMechanism.data);
1807
+ exceptionValue0.mechanism.data = mergedData;
1808
+ }
1809
+ }
1810
+ const defaultRetryAfter = 60 * 1000; // 60 seconds
1811
+ /**
1812
+ * Extracts Retry-After value from the request header or returns default value
1813
+ * @param now current unix timestamp
1814
+ * @param header string representation of 'Retry-After' header
1815
+ */
1816
+ function parseRetryAfterHeader(now, header) {
1817
+ if (!header) {
1818
+ return defaultRetryAfter;
1819
+ }
1820
+ const headerDelay = parseInt(`${header}`, 10);
1821
+ if (!isNaN(headerDelay)) {
1822
+ return headerDelay * 1000;
1823
+ }
1824
+ const headerDate = Date.parse(`${header}`);
1825
+ if (!isNaN(headerDate)) {
1826
+ return headerDate - now;
1827
+ }
1828
+ return defaultRetryAfter;
1829
+ }
1830
+ /**
1831
+ * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
1832
+ * in question), and marks it captured if not.
1833
+ *
1834
+ * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
1835
+ * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
1836
+ * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
1837
+ * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
1838
+ * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
1839
+ * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
1840
+ * see it.
1841
+ *
1842
+ * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
1843
+ * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
1844
+ * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
1845
+ * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
1846
+ * must be done before the exception captured.
1847
+ *
1848
+ * @param A thrown exception to check or flag as having been seen
1849
+ * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
1850
+ */
1851
+ function checkOrSetAlreadyCaught(exception) {
1852
+ var _a;
1853
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1854
+ if ((_a = exception) === null || _a === void 0 ? void 0 : _a.__sentry_captured__) {
1855
+ return true;
1856
+ }
1857
+ try {
1858
+ // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
1859
+ // `ExtraErrorData` integration
1860
+ Object.defineProperty(exception, '__sentry_captured__', {
1861
+ value: true,
1862
+ });
1863
+ }
1864
+ catch (err) {
1865
+ // `exception` is a primitive, so we can't mark it seen
1866
+ }
1867
+ return false;
1868
+ }
1869
+
1818
1870
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
1819
1871
  /** SyncPromise internal states */
1820
1872
  var States;
@@ -3620,6 +3672,7 @@ var Sentry = (function (exports) {
3620
3672
  }
3621
3673
 
3622
3674
  /* eslint-disable max-lines */
3675
+ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
3623
3676
  /**
3624
3677
  * Base implementation for all JavaScript SDK clients.
3625
3678
  *
@@ -3675,6 +3728,11 @@ var Sentry = (function (exports) {
3675
3728
  */
3676
3729
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
3677
3730
  captureException(exception, hint, scope) {
3731
+ // ensure we haven't captured this very object before
3732
+ if (checkOrSetAlreadyCaught(exception)) {
3733
+ logger.log(ALREADY_SEEN_ERROR);
3734
+ return;
3735
+ }
3678
3736
  let eventId = hint && hint.event_id;
3679
3737
  this._process(this._getBackend()
3680
3738
  .eventFromException(exception, hint)
@@ -3703,6 +3761,12 @@ var Sentry = (function (exports) {
3703
3761
  * @inheritDoc
3704
3762
  */
3705
3763
  captureEvent(event, hint, scope) {
3764
+ var _a;
3765
+ // ensure we haven't captured this very object before
3766
+ if (((_a = hint) === null || _a === void 0 ? void 0 : _a.originalException) && checkOrSetAlreadyCaught(hint.originalException)) {
3767
+ logger.log(ALREADY_SEEN_ERROR);
3768
+ return;
3769
+ }
3706
3770
  let eventId = hint && hint.event_id;
3707
3771
  this._process(this._captureEvent(event, hint, scope).then(result => {
3708
3772
  eventId = result;
@@ -4298,7 +4362,7 @@ var Sentry = (function (exports) {
4298
4362
  hub.bindClient(client);
4299
4363
  }
4300
4364
 
4301
- const SDK_VERSION = '6.13.3';
4365
+ const SDK_VERSION = '6.14.0';
4302
4366
 
4303
4367
  let originalFunctionToString;
4304
4368
  /** Patch toString calls to return proper name for wrapped functions */
@@ -4869,10 +4933,7 @@ var Sentry = (function (exports) {
4869
4933
  const event = eventFromUnknownInput(exception, syntheticException, {
4870
4934
  attachStacktrace: options.attachStacktrace,
4871
4935
  });
4872
- addExceptionMechanism(event, {
4873
- handled: true,
4874
- type: 'generic',
4875
- });
4936
+ addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
4876
4937
  event.level = exports.Severity.Error;
4877
4938
  if (hint && hint.event_id) {
4878
4939
  event.event_id = hint.event_id;
@@ -5139,7 +5200,7 @@ var Sentry = (function (exports) {
5139
5200
  logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
5140
5201
  const url = this._api.getEnvelopeEndpointWithUrlEncodedAuth();
5141
5202
  // Envelope header is required to be at least an empty object
5142
- const envelopeHeader = JSON.stringify({});
5203
+ const envelopeHeader = JSON.stringify(Object.assign({}, (this.options.tunnel && { dsn: this._api.getDsn().toString() })));
5143
5204
  const itemHeaders = JSON.stringify({
5144
5205
  type: 'client_report',
5145
5206
  });