@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.
package/build/bundle.js CHANGED
@@ -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
  /*! *****************************************************************************
4
4
  Copyright (c) Microsoft Corporation. All rights reserved.
@@ -241,6 +241,49 @@ var Sentry = (function (exports) {
241
241
  });
242
242
  }
243
243
 
244
+ /**
245
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
246
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
247
+ */
248
+ /**
249
+ * Checks whether we're in the Node.js or Browser environment
250
+ *
251
+ * @returns Answer to given question
252
+ */
253
+ function isNodeEnv() {
254
+ return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
255
+ }
256
+ /**
257
+ * Requires a module which is protected against bundler minification.
258
+ *
259
+ * @param request The module path to resolve
260
+ */
261
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
262
+ function dynamicRequire(mod, request) {
263
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
264
+ return mod.require(request);
265
+ }
266
+
267
+ /**
268
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
269
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
270
+ */
271
+ var fallbackGlobalObject = {};
272
+ /**
273
+ * Safely get global scope object
274
+ *
275
+ * @returns Global scope object
276
+ */
277
+ function getGlobalObject() {
278
+ return (isNodeEnv()
279
+ ? global
280
+ : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
281
+ ? window // eslint-disable-line no-restricted-globals
282
+ : typeof self !== 'undefined'
283
+ ? self
284
+ : fallbackGlobalObject);
285
+ }
286
+
244
287
  /* eslint-disable @typescript-eslint/no-explicit-any */
245
288
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
246
289
  /**
@@ -476,6 +519,18 @@ var Sentry = (function (exports) {
476
519
  }
477
520
  }
478
521
  return out.join('');
522
+ }
523
+ /**
524
+ * A safe form of location.href
525
+ */
526
+ function getLocationHref() {
527
+ var global = getGlobalObject();
528
+ try {
529
+ return global.document.location.href;
530
+ }
531
+ catch (oO) {
532
+ return '';
533
+ }
479
534
  }
480
535
 
481
536
  var setPrototypeOf = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties);
@@ -606,175 +661,17 @@ var Sentry = (function (exports) {
606
661
  return Dsn;
607
662
  }());
608
663
 
664
+ // TODO: Implement different loggers for different environments
665
+ var global$1 = getGlobalObject();
666
+ /** Prefix for logging strings */
667
+ var PREFIX = 'Sentry Logger ';
609
668
  /**
610
- * Checks whether we're in the Node.js or Browser environment
611
- *
612
- * @returns Answer to given question
613
- */
614
- function isNodeEnv() {
615
- return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
616
- }
617
- /**
618
- * Requires a module which is protected against bundler minification.
619
- *
620
- * @param request The module path to resolve
621
- */
622
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
623
- function dynamicRequire(mod, request) {
624
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
625
- return mod.require(request);
626
- }
627
-
628
- /**
629
- * Truncates given string to the maximum characters count
630
- *
631
- * @param str An object that contains serializable values
632
- * @param max Maximum number of characters in truncated string (0 = unlimited)
633
- * @returns string Encoded
634
- */
635
- function truncate(str, max) {
636
- if (max === void 0) { max = 0; }
637
- if (typeof str !== 'string' || max === 0) {
638
- return str;
639
- }
640
- return str.length <= max ? str : str.substr(0, max) + "...";
641
- }
642
- /**
643
- * Join values in array
644
- * @param input array of values to be joined together
645
- * @param delimiter string to be placed in-between values
646
- * @returns Joined values
647
- */
648
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
649
- function safeJoin(input, delimiter) {
650
- if (!Array.isArray(input)) {
651
- return '';
652
- }
653
- var output = [];
654
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
655
- for (var i = 0; i < input.length; i++) {
656
- var value = input[i];
657
- try {
658
- output.push(String(value));
659
- }
660
- catch (e) {
661
- output.push('[value cannot be serialized]');
662
- }
663
- }
664
- return output.join(delimiter);
665
- }
666
- /**
667
- * Checks if the value matches a regex or includes the string
668
- * @param value The string value to be checked against
669
- * @param pattern Either a regex or a string that must be contained in value
670
- */
671
- function isMatchingPattern(value, pattern) {
672
- if (!isString(value)) {
673
- return false;
674
- }
675
- if (isRegExp(pattern)) {
676
- return pattern.test(value);
677
- }
678
- if (typeof pattern === 'string') {
679
- return value.indexOf(pattern) !== -1;
680
- }
681
- return false;
682
- }
683
-
684
- var fallbackGlobalObject = {};
685
- /**
686
- * Safely get global scope object
687
- *
688
- * @returns Global scope object
689
- */
690
- function getGlobalObject() {
691
- return (isNodeEnv()
692
- ? global
693
- : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals
694
- ? window // eslint-disable-line no-restricted-globals
695
- : typeof self !== 'undefined'
696
- ? self
697
- : fallbackGlobalObject);
698
- }
699
- /**
700
- * UUID4 generator
669
+ * Temporarily unwrap `console.log` and friends in order to perform the given callback using the original methods.
670
+ * Restores wrapping after the callback completes.
701
671
  *
702
- * @returns string Generated UUID4.
672
+ * @param callback The function to run against the original `console` messages
673
+ * @returns The results of the callback
703
674
  */
704
- function uuid4() {
705
- var global = getGlobalObject();
706
- var crypto = global.crypto || global.msCrypto;
707
- if (!(crypto === void 0) && crypto.getRandomValues) {
708
- // Use window.crypto API if available
709
- var arr = new Uint16Array(8);
710
- crypto.getRandomValues(arr);
711
- // set 4 in byte 7
712
- // eslint-disable-next-line no-bitwise
713
- arr[3] = (arr[3] & 0xfff) | 0x4000;
714
- // set 2 most significant bits of byte 9 to '10'
715
- // eslint-disable-next-line no-bitwise
716
- arr[4] = (arr[4] & 0x3fff) | 0x8000;
717
- var pad = function (num) {
718
- var v = num.toString(16);
719
- while (v.length < 4) {
720
- v = "0" + v;
721
- }
722
- return v;
723
- };
724
- 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]));
725
- }
726
- // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
727
- return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
728
- // eslint-disable-next-line no-bitwise
729
- var r = (Math.random() * 16) | 0;
730
- // eslint-disable-next-line no-bitwise
731
- var v = c === 'x' ? r : (r & 0x3) | 0x8;
732
- return v.toString(16);
733
- });
734
- }
735
- /**
736
- * Parses string form of URL into an object
737
- * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
738
- * // intentionally using regex and not <a/> href parsing trick because React Native and other
739
- * // environments where DOM might not be available
740
- * @returns parsed URL object
741
- */
742
- function parseUrl(url) {
743
- if (!url) {
744
- return {};
745
- }
746
- var match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
747
- if (!match) {
748
- return {};
749
- }
750
- // coerce to undefined values to empty string so we don't get 'undefined'
751
- var query = match[6] || '';
752
- var fragment = match[8] || '';
753
- return {
754
- host: match[4],
755
- path: match[5],
756
- protocol: match[2],
757
- relative: match[5] + query + fragment,
758
- };
759
- }
760
- /**
761
- * Extracts either message or type+value from an event that can be used for user-facing logs
762
- * @returns event's description
763
- */
764
- function getEventDescription(event) {
765
- if (event.message) {
766
- return event.message;
767
- }
768
- if (event.exception && event.exception.values && event.exception.values[0]) {
769
- var exception = event.exception.values[0];
770
- if (exception.type && exception.value) {
771
- return exception.type + ": " + exception.value;
772
- }
773
- return exception.type || exception.value || event.event_id || '<unknown>';
774
- }
775
- return event.event_id || '<unknown>';
776
- }
777
- /** JSDoc */
778
675
  function consoleSandbox(callback) {
779
676
  var global = getGlobalObject();
780
677
  var levels = ['debug', 'info', 'warn', 'error', 'log', 'assert'];
@@ -800,81 +697,6 @@ var Sentry = (function (exports) {
800
697
  });
801
698
  return result;
802
699
  }
803
- /**
804
- * Adds exception values, type and value to an synthetic Exception.
805
- * @param event The event to modify.
806
- * @param value Value of the exception.
807
- * @param type Type of the exception.
808
- * @hidden
809
- */
810
- function addExceptionTypeValue(event, value, type) {
811
- event.exception = event.exception || {};
812
- event.exception.values = event.exception.values || [];
813
- event.exception.values[0] = event.exception.values[0] || {};
814
- event.exception.values[0].value = event.exception.values[0].value || value || '';
815
- event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
816
- }
817
- /**
818
- * Adds exception mechanism to a given event.
819
- * @param event The event to modify.
820
- * @param mechanism Mechanism of the mechanism.
821
- * @hidden
822
- */
823
- function addExceptionMechanism(event, mechanism) {
824
- if (mechanism === void 0) { mechanism = {}; }
825
- // TODO: Use real type with `keyof Mechanism` thingy and maybe make it better?
826
- try {
827
- // @ts-ignore Type 'Mechanism | {}' is not assignable to type 'Mechanism | undefined'
828
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
829
- event.exception.values[0].mechanism = event.exception.values[0].mechanism || {};
830
- Object.keys(mechanism).forEach(function (key) {
831
- // @ts-ignore Mechanism has no index signature
832
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
833
- event.exception.values[0].mechanism[key] = mechanism[key];
834
- });
835
- }
836
- catch (_oO) {
837
- // no-empty
838
- }
839
- }
840
- /**
841
- * A safe form of location.href
842
- */
843
- function getLocationHref() {
844
- var global = getGlobalObject();
845
- try {
846
- return global.document.location.href;
847
- }
848
- catch (oO) {
849
- return '';
850
- }
851
- }
852
- var defaultRetryAfter = 60 * 1000; // 60 seconds
853
- /**
854
- * Extracts Retry-After value from the request header or returns default value
855
- * @param now current unix timestamp
856
- * @param header string representation of 'Retry-After' header
857
- */
858
- function parseRetryAfterHeader(now, header) {
859
- if (!header) {
860
- return defaultRetryAfter;
861
- }
862
- var headerDelay = parseInt("" + header, 10);
863
- if (!isNaN(headerDelay)) {
864
- return headerDelay * 1000;
865
- }
866
- var headerDate = Date.parse("" + header);
867
- if (!isNaN(headerDate)) {
868
- return headerDate - now;
869
- }
870
- return defaultRetryAfter;
871
- }
872
-
873
- /* eslint-disable @typescript-eslint/no-explicit-any */
874
- // TODO: Implement different loggers for different environments
875
- var global$1 = getGlobalObject();
876
- /** Prefix for logging strings */
877
- var PREFIX = 'Sentry Logger ';
878
700
  /** JSDoc */
879
701
  var Logger = /** @class */ (function () {
880
702
  /** JSDoc */
@@ -1005,6 +827,62 @@ var Sentry = (function (exports) {
1005
827
  }
1006
828
  }
1007
829
 
830
+ /**
831
+ * Truncates given string to the maximum characters count
832
+ *
833
+ * @param str An object that contains serializable values
834
+ * @param max Maximum number of characters in truncated string (0 = unlimited)
835
+ * @returns string Encoded
836
+ */
837
+ function truncate(str, max) {
838
+ if (max === void 0) { max = 0; }
839
+ if (typeof str !== 'string' || max === 0) {
840
+ return str;
841
+ }
842
+ return str.length <= max ? str : str.substr(0, max) + "...";
843
+ }
844
+ /**
845
+ * Join values in array
846
+ * @param input array of values to be joined together
847
+ * @param delimiter string to be placed in-between values
848
+ * @returns Joined values
849
+ */
850
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
851
+ function safeJoin(input, delimiter) {
852
+ if (!Array.isArray(input)) {
853
+ return '';
854
+ }
855
+ var output = [];
856
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
857
+ for (var i = 0; i < input.length; i++) {
858
+ var value = input[i];
859
+ try {
860
+ output.push(String(value));
861
+ }
862
+ catch (e) {
863
+ output.push('[value cannot be serialized]');
864
+ }
865
+ }
866
+ return output.join(delimiter);
867
+ }
868
+ /**
869
+ * Checks if the value matches a regex or includes the string
870
+ * @param value The string value to be checked against
871
+ * @param pattern Either a regex or a string that must be contained in value
872
+ */
873
+ function isMatchingPattern(value, pattern) {
874
+ if (!isString(value)) {
875
+ return false;
876
+ }
877
+ if (isRegExp(pattern)) {
878
+ return pattern.test(value);
879
+ }
880
+ if (typeof pattern === 'string') {
881
+ return value.indexOf(pattern) !== -1;
882
+ }
883
+ return false;
884
+ }
885
+
1008
886
  /**
1009
887
  * Replace a method in an object with a wrapped version of itself.
1010
888
  *
@@ -1980,6 +1858,179 @@ var Sentry = (function (exports) {
1980
1858
  };
1981
1859
  }
1982
1860
 
1861
+ /**
1862
+ * UUID4 generator
1863
+ *
1864
+ * @returns string Generated UUID4.
1865
+ */
1866
+ function uuid4() {
1867
+ var global = getGlobalObject();
1868
+ var crypto = global.crypto || global.msCrypto;
1869
+ if (!(crypto === void 0) && crypto.getRandomValues) {
1870
+ // Use window.crypto API if available
1871
+ var arr = new Uint16Array(8);
1872
+ crypto.getRandomValues(arr);
1873
+ // set 4 in byte 7
1874
+ // eslint-disable-next-line no-bitwise
1875
+ arr[3] = (arr[3] & 0xfff) | 0x4000;
1876
+ // set 2 most significant bits of byte 9 to '10'
1877
+ // eslint-disable-next-line no-bitwise
1878
+ arr[4] = (arr[4] & 0x3fff) | 0x8000;
1879
+ var pad = function (num) {
1880
+ var v = num.toString(16);
1881
+ while (v.length < 4) {
1882
+ v = "0" + v;
1883
+ }
1884
+ return v;
1885
+ };
1886
+ 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]));
1887
+ }
1888
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
1889
+ return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
1890
+ // eslint-disable-next-line no-bitwise
1891
+ var r = (Math.random() * 16) | 0;
1892
+ // eslint-disable-next-line no-bitwise
1893
+ var v = c === 'x' ? r : (r & 0x3) | 0x8;
1894
+ return v.toString(16);
1895
+ });
1896
+ }
1897
+ /**
1898
+ * Parses string form of URL into an object
1899
+ * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
1900
+ * // intentionally using regex and not <a/> href parsing trick because React Native and other
1901
+ * // environments where DOM might not be available
1902
+ * @returns parsed URL object
1903
+ */
1904
+ function parseUrl(url) {
1905
+ if (!url) {
1906
+ return {};
1907
+ }
1908
+ var match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
1909
+ if (!match) {
1910
+ return {};
1911
+ }
1912
+ // coerce to undefined values to empty string so we don't get 'undefined'
1913
+ var query = match[6] || '';
1914
+ var fragment = match[8] || '';
1915
+ return {
1916
+ host: match[4],
1917
+ path: match[5],
1918
+ protocol: match[2],
1919
+ relative: match[5] + query + fragment,
1920
+ };
1921
+ }
1922
+ /**
1923
+ * Extracts either message or type+value from an event that can be used for user-facing logs
1924
+ * @returns event's description
1925
+ */
1926
+ function getEventDescription(event) {
1927
+ if (event.message) {
1928
+ return event.message;
1929
+ }
1930
+ if (event.exception && event.exception.values && event.exception.values[0]) {
1931
+ var exception = event.exception.values[0];
1932
+ if (exception.type && exception.value) {
1933
+ return exception.type + ": " + exception.value;
1934
+ }
1935
+ return exception.type || exception.value || event.event_id || '<unknown>';
1936
+ }
1937
+ return event.event_id || '<unknown>';
1938
+ }
1939
+ /**
1940
+ * Adds exception values, type and value to an synthetic Exception.
1941
+ * @param event The event to modify.
1942
+ * @param value Value of the exception.
1943
+ * @param type Type of the exception.
1944
+ * @hidden
1945
+ */
1946
+ function addExceptionTypeValue(event, value, type) {
1947
+ event.exception = event.exception || {};
1948
+ event.exception.values = event.exception.values || [];
1949
+ event.exception.values[0] = event.exception.values[0] || {};
1950
+ event.exception.values[0].value = event.exception.values[0].value || value || '';
1951
+ event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
1952
+ }
1953
+ /**
1954
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
1955
+ *
1956
+ * @param event The event to modify.
1957
+ * @param newMechanism Mechanism data to add to the event.
1958
+ * @hidden
1959
+ */
1960
+ function addExceptionMechanism(event, newMechanism) {
1961
+ var _a;
1962
+ if (!event.exception || !event.exception.values) {
1963
+ return;
1964
+ }
1965
+ var exceptionValue0 = event.exception.values[0];
1966
+ var defaultMechanism = { type: 'generic', handled: true };
1967
+ var currentMechanism = exceptionValue0.mechanism;
1968
+ exceptionValue0.mechanism = __assign(__assign(__assign({}, defaultMechanism), currentMechanism), newMechanism);
1969
+ if (newMechanism && 'data' in newMechanism) {
1970
+ var mergedData = __assign(__assign({}, (_a = currentMechanism) === null || _a === void 0 ? void 0 : _a.data), newMechanism.data);
1971
+ exceptionValue0.mechanism.data = mergedData;
1972
+ }
1973
+ }
1974
+ var defaultRetryAfter = 60 * 1000; // 60 seconds
1975
+ /**
1976
+ * Extracts Retry-After value from the request header or returns default value
1977
+ * @param now current unix timestamp
1978
+ * @param header string representation of 'Retry-After' header
1979
+ */
1980
+ function parseRetryAfterHeader(now, header) {
1981
+ if (!header) {
1982
+ return defaultRetryAfter;
1983
+ }
1984
+ var headerDelay = parseInt("" + header, 10);
1985
+ if (!isNaN(headerDelay)) {
1986
+ return headerDelay * 1000;
1987
+ }
1988
+ var headerDate = Date.parse("" + header);
1989
+ if (!isNaN(headerDate)) {
1990
+ return headerDate - now;
1991
+ }
1992
+ return defaultRetryAfter;
1993
+ }
1994
+ /**
1995
+ * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
1996
+ * in question), and marks it captured if not.
1997
+ *
1998
+ * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
1999
+ * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
2000
+ * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
2001
+ * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
2002
+ * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
2003
+ * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
2004
+ * see it.
2005
+ *
2006
+ * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
2007
+ * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
2008
+ * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
2009
+ * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
2010
+ * must be done before the exception captured.
2011
+ *
2012
+ * @param A thrown exception to check or flag as having been seen
2013
+ * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
2014
+ */
2015
+ function checkOrSetAlreadyCaught(exception) {
2016
+ var _a;
2017
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
2018
+ if ((_a = exception) === null || _a === void 0 ? void 0 : _a.__sentry_captured__) {
2019
+ return true;
2020
+ }
2021
+ try {
2022
+ // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
2023
+ // `ExtraErrorData` integration
2024
+ Object.defineProperty(exception, '__sentry_captured__', {
2025
+ value: true,
2026
+ });
2027
+ }
2028
+ catch (err) {
2029
+ // `exception` is a primitive, so we can't mark it seen
2030
+ }
2031
+ return false;
2032
+ }
2033
+
1983
2034
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
1984
2035
  /** SyncPromise internal states */
1985
2036
  var States;
@@ -3819,6 +3870,7 @@ var Sentry = (function (exports) {
3819
3870
  return integrations;
3820
3871
  }
3821
3872
 
3873
+ var ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
3822
3874
  /**
3823
3875
  * Base implementation for all JavaScript SDK clients.
3824
3876
  *
@@ -3875,6 +3927,11 @@ var Sentry = (function (exports) {
3875
3927
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
3876
3928
  BaseClient.prototype.captureException = function (exception, hint, scope) {
3877
3929
  var _this = this;
3930
+ // ensure we haven't captured this very object before
3931
+ if (checkOrSetAlreadyCaught(exception)) {
3932
+ logger.log(ALREADY_SEEN_ERROR);
3933
+ return;
3934
+ }
3878
3935
  var eventId = hint && hint.event_id;
3879
3936
  this._process(this._getBackend()
3880
3937
  .eventFromException(exception, hint)
@@ -3904,6 +3961,12 @@ var Sentry = (function (exports) {
3904
3961
  * @inheritDoc
3905
3962
  */
3906
3963
  BaseClient.prototype.captureEvent = function (event, hint, scope) {
3964
+ var _a;
3965
+ // ensure we haven't captured this very object before
3966
+ if (((_a = hint) === null || _a === void 0 ? void 0 : _a.originalException) && checkOrSetAlreadyCaught(hint.originalException)) {
3967
+ logger.log(ALREADY_SEEN_ERROR);
3968
+ return;
3969
+ }
3907
3970
  var eventId = hint && hint.event_id;
3908
3971
  this._process(this._captureEvent(event, hint, scope).then(function (result) {
3909
3972
  eventId = result;
@@ -4496,7 +4559,7 @@ var Sentry = (function (exports) {
4496
4559
  hub.bindClient(client);
4497
4560
  }
4498
4561
 
4499
- var SDK_VERSION = '6.13.3';
4562
+ var SDK_VERSION = '6.14.0';
4500
4563
 
4501
4564
  var originalFunctionToString;
4502
4565
  /** Patch toString calls to return proper name for wrapped functions */
@@ -5060,10 +5123,7 @@ var Sentry = (function (exports) {
5060
5123
  var event = eventFromUnknownInput(exception, syntheticException, {
5061
5124
  attachStacktrace: options.attachStacktrace,
5062
5125
  });
5063
- addExceptionMechanism(event, {
5064
- handled: true,
5065
- type: 'generic',
5066
- });
5126
+ addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
5067
5127
  event.level = exports.Severity.Error;
5068
5128
  if (hint && hint.event_id) {
5069
5129
  event.event_id = hint.event_id;
@@ -5334,7 +5394,7 @@ var Sentry = (function (exports) {
5334
5394
  logger.log("Flushing outcomes:\n" + JSON.stringify(outcomes, null, 2));
5335
5395
  var url = this._api.getEnvelopeEndpointWithUrlEncodedAuth();
5336
5396
  // Envelope header is required to be at least an empty object
5337
- var envelopeHeader = JSON.stringify({});
5397
+ var envelopeHeader = JSON.stringify(__assign({}, (this.options.tunnel && { dsn: this._api.getDsn().toString() })));
5338
5398
  var itemHeaders = JSON.stringify({
5339
5399
  type: 'client_report',
5340
5400
  });