@sentry/browser 6.19.1 → 6.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/bundle.debug.min.js +2 -2
- package/bundles/bundle.debug.min.js.map +1 -1
- package/bundles/bundle.es6.debug.min.js +2 -2
- package/bundles/bundle.es6.debug.min.js.map +1 -1
- package/bundles/bundle.es6.js +658 -628
- package/bundles/bundle.es6.js.map +1 -1
- package/bundles/bundle.es6.min.js +2 -2
- package/bundles/bundle.es6.min.js.map +1 -1
- package/bundles/bundle.js +668 -636
- package/bundles/bundle.js.map +1 -1
- package/bundles/bundle.min.js +2 -2
- package/bundles/bundle.min.js.map +1 -1
- package/package.json +5 -5
package/bundles/bundle.es6.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @sentry/browser 6.19.
|
|
1
|
+
/*! @sentry/browser 6.19.2 (f49c509) | https://github.com/getsentry/sentry-javascript */
|
|
2
2
|
var Sentry = (function (exports) {
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -525,114 +525,6 @@ var Sentry = (function (exports) {
|
|
|
525
525
|
global$6.__SENTRY__ = sentryGlobal;
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
529
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
530
|
-
/**
|
|
531
|
-
* Helper to decycle json objects
|
|
532
|
-
*/
|
|
533
|
-
function memoBuilder() {
|
|
534
|
-
const hasWeakSet = typeof WeakSet === 'function';
|
|
535
|
-
const inner = hasWeakSet ? new WeakSet() : [];
|
|
536
|
-
function memoize(obj) {
|
|
537
|
-
if (hasWeakSet) {
|
|
538
|
-
if (inner.has(obj)) {
|
|
539
|
-
return true;
|
|
540
|
-
}
|
|
541
|
-
inner.add(obj);
|
|
542
|
-
return false;
|
|
543
|
-
}
|
|
544
|
-
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
545
|
-
for (let i = 0; i < inner.length; i++) {
|
|
546
|
-
const value = inner[i];
|
|
547
|
-
if (value === obj) {
|
|
548
|
-
return true;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
inner.push(obj);
|
|
552
|
-
return false;
|
|
553
|
-
}
|
|
554
|
-
function unmemoize(obj) {
|
|
555
|
-
if (hasWeakSet) {
|
|
556
|
-
inner.delete(obj);
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
for (let i = 0; i < inner.length; i++) {
|
|
560
|
-
if (inner[i] === obj) {
|
|
561
|
-
inner.splice(i, 1);
|
|
562
|
-
break;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return [memoize, unmemoize];
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
const STACKTRACE_LIMIT = 50;
|
|
571
|
-
/**
|
|
572
|
-
* Creates a stack parser with the supplied line parsers
|
|
573
|
-
*
|
|
574
|
-
* StackFrames are returned in the correct order for Sentry Exception
|
|
575
|
-
* frames and with Sentry SDK internal frames removed from the top and bottom
|
|
576
|
-
*
|
|
577
|
-
*/
|
|
578
|
-
function createStackParser(...parsers) {
|
|
579
|
-
const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);
|
|
580
|
-
return (stack, skipFirst = 0) => {
|
|
581
|
-
const frames = [];
|
|
582
|
-
for (const line of stack.split('\n').slice(skipFirst)) {
|
|
583
|
-
for (const parser of sortedParsers) {
|
|
584
|
-
const frame = parser(line);
|
|
585
|
-
if (frame) {
|
|
586
|
-
frames.push(frame);
|
|
587
|
-
break;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
return stripSentryFramesAndReverse(frames);
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* @hidden
|
|
596
|
-
*/
|
|
597
|
-
function stripSentryFramesAndReverse(stack) {
|
|
598
|
-
if (!stack.length) {
|
|
599
|
-
return [];
|
|
600
|
-
}
|
|
601
|
-
let localStack = stack;
|
|
602
|
-
const firstFrameFunction = localStack[0].function || '';
|
|
603
|
-
const lastFrameFunction = localStack[localStack.length - 1].function || '';
|
|
604
|
-
// If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
|
|
605
|
-
if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
|
|
606
|
-
localStack = localStack.slice(1);
|
|
607
|
-
}
|
|
608
|
-
// If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)
|
|
609
|
-
if (lastFrameFunction.indexOf('sentryWrapped') !== -1) {
|
|
610
|
-
localStack = localStack.slice(0, -1);
|
|
611
|
-
}
|
|
612
|
-
// The frame where the crash happened, should be the last entry in the array
|
|
613
|
-
return localStack
|
|
614
|
-
.slice(0, STACKTRACE_LIMIT)
|
|
615
|
-
.map(frame => (Object.assign(Object.assign({}, frame), { filename: frame.filename || localStack[0].filename, function: frame.function || '?' })))
|
|
616
|
-
.reverse();
|
|
617
|
-
}
|
|
618
|
-
const defaultFunctionName = '<anonymous>';
|
|
619
|
-
/**
|
|
620
|
-
* Safely extract function name from itself
|
|
621
|
-
*/
|
|
622
|
-
function getFunctionName(fn) {
|
|
623
|
-
try {
|
|
624
|
-
if (!fn || typeof fn !== 'function') {
|
|
625
|
-
return defaultFunctionName;
|
|
626
|
-
}
|
|
627
|
-
return fn.name || defaultFunctionName;
|
|
628
|
-
}
|
|
629
|
-
catch (e) {
|
|
630
|
-
// Just accessing custom props in some Selenium environments
|
|
631
|
-
// can cause a "Permission denied" exception (see raven-js#495).
|
|
632
|
-
return defaultFunctionName;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
528
|
/**
|
|
637
529
|
* Truncates given string to the maximum characters count
|
|
638
530
|
*
|
|
@@ -789,218 +681,38 @@ var Sentry = (function (exports) {
|
|
|
789
681
|
}
|
|
790
682
|
if (isEvent(value)) {
|
|
791
683
|
const event = value;
|
|
792
|
-
const source = {};
|
|
793
|
-
// Accessing event attributes can throw (see https://github.com/getsentry/sentry-javascript/issues/768 and
|
|
794
|
-
// https://github.com/getsentry/sentry-javascript/issues/838), but accessing `type` hasn't been wrapped in a
|
|
795
|
-
// try-catch in at least two years and no one's complained, so that's likely not an issue anymore
|
|
796
|
-
source.type = event.type;
|
|
797
|
-
try {
|
|
798
|
-
source.target = isElement(event.target)
|
|
799
|
-
? htmlTreeAsString(event.target)
|
|
800
|
-
: Object.prototype.toString.call(event.target);
|
|
801
|
-
}
|
|
802
|
-
catch (_oO) {
|
|
803
|
-
source.target = '<unknown>';
|
|
804
|
-
}
|
|
805
|
-
try {
|
|
806
|
-
source.currentTarget = isElement(event.currentTarget)
|
|
807
|
-
? htmlTreeAsString(event.currentTarget)
|
|
808
|
-
: Object.prototype.toString.call(event.currentTarget);
|
|
809
|
-
}
|
|
810
|
-
catch (_oO) {
|
|
811
|
-
source.currentTarget = '<unknown>';
|
|
812
|
-
}
|
|
813
|
-
if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {
|
|
814
|
-
source.detail = event.detail;
|
|
815
|
-
}
|
|
816
|
-
for (const attr in event) {
|
|
817
|
-
if (Object.prototype.hasOwnProperty.call(event, attr)) {
|
|
818
|
-
source[attr] = event[attr];
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
return source;
|
|
822
|
-
}
|
|
823
|
-
return value;
|
|
824
|
-
}
|
|
825
|
-
/** Calculates bytes size of input string */
|
|
826
|
-
function utf8Length(value) {
|
|
827
|
-
// eslint-disable-next-line no-bitwise
|
|
828
|
-
return ~-encodeURI(value).split(/%..|./).length;
|
|
829
|
-
}
|
|
830
|
-
/** Calculates bytes size of input object */
|
|
831
|
-
function jsonSize(value) {
|
|
832
|
-
return utf8Length(JSON.stringify(value));
|
|
833
|
-
}
|
|
834
|
-
/** JSDoc */
|
|
835
|
-
function normalizeToSize(object,
|
|
836
|
-
// Default Node.js REPL depth
|
|
837
|
-
depth = 3,
|
|
838
|
-
// 100kB, as 200kB is max payload size, so half sounds reasonable
|
|
839
|
-
maxSize = 100 * 1024) {
|
|
840
|
-
const serialized = normalize(object, depth);
|
|
841
|
-
if (jsonSize(serialized) > maxSize) {
|
|
842
|
-
return normalizeToSize(object, depth - 1, maxSize);
|
|
843
|
-
}
|
|
844
|
-
return serialized;
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* Transform any non-primitive, BigInt, or Symbol-type value into a string. Acts as a no-op on strings, numbers,
|
|
848
|
-
* booleans, null, and undefined.
|
|
849
|
-
*
|
|
850
|
-
* @param value The value to stringify
|
|
851
|
-
* @returns For non-primitive, BigInt, and Symbol-type values, a string denoting the value's type, type and value, or
|
|
852
|
-
* type and `description` property, respectively. For non-BigInt, non-Symbol primitives, returns the original value,
|
|
853
|
-
* unchanged.
|
|
854
|
-
*/
|
|
855
|
-
function serializeValue(value) {
|
|
856
|
-
// Node.js REPL notation
|
|
857
|
-
if (typeof value === 'string') {
|
|
858
|
-
return value;
|
|
859
|
-
}
|
|
860
|
-
const type = Object.prototype.toString.call(value);
|
|
861
|
-
if (type === '[object Object]') {
|
|
862
|
-
return '[Object]';
|
|
863
|
-
}
|
|
864
|
-
if (type === '[object Array]') {
|
|
865
|
-
return '[Array]';
|
|
866
|
-
}
|
|
867
|
-
// `makeSerializable` provides a string representation of certain non-serializable values. For all others, it's a
|
|
868
|
-
// pass-through.
|
|
869
|
-
const serializable = makeSerializable(value);
|
|
870
|
-
return isPrimitive(serializable) ? serializable : type;
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* makeSerializable()
|
|
874
|
-
*
|
|
875
|
-
* Takes unserializable input and make it serializer-friendly.
|
|
876
|
-
*
|
|
877
|
-
* Handles globals, functions, `undefined`, `NaN`, and other non-serializable values.
|
|
878
|
-
*/
|
|
879
|
-
function makeSerializable(value, key) {
|
|
880
|
-
if (key === 'domain' && value && typeof value === 'object' && value._events) {
|
|
881
|
-
return '[Domain]';
|
|
882
|
-
}
|
|
883
|
-
if (key === 'domainEmitter') {
|
|
884
|
-
return '[DomainEmitter]';
|
|
885
|
-
}
|
|
886
|
-
if (typeof global !== 'undefined' && value === global) {
|
|
887
|
-
return '[Global]';
|
|
888
|
-
}
|
|
889
|
-
// It's safe to use `window` and `document` here in this manner, as we are asserting using `typeof` first
|
|
890
|
-
// which won't throw if they are not present.
|
|
891
|
-
// eslint-disable-next-line no-restricted-globals
|
|
892
|
-
if (typeof window !== 'undefined' && value === window) {
|
|
893
|
-
return '[Window]';
|
|
894
|
-
}
|
|
895
|
-
// eslint-disable-next-line no-restricted-globals
|
|
896
|
-
if (typeof document !== 'undefined' && value === document) {
|
|
897
|
-
return '[Document]';
|
|
898
|
-
}
|
|
899
|
-
// React's SyntheticEvent thingy
|
|
900
|
-
if (isSyntheticEvent(value)) {
|
|
901
|
-
return '[SyntheticEvent]';
|
|
902
|
-
}
|
|
903
|
-
if (typeof value === 'number' && value !== value) {
|
|
904
|
-
return '[NaN]';
|
|
905
|
-
}
|
|
906
|
-
if (value === void 0) {
|
|
907
|
-
return '[undefined]';
|
|
908
|
-
}
|
|
909
|
-
if (typeof value === 'function') {
|
|
910
|
-
return `[Function: ${getFunctionName(value)}]`;
|
|
911
|
-
}
|
|
912
|
-
// symbols and bigints are considered primitives by TS, but aren't natively JSON-serilaizable
|
|
913
|
-
if (typeof value === 'symbol') {
|
|
914
|
-
return `[${String(value)}]`;
|
|
915
|
-
}
|
|
916
|
-
if (typeof value === 'bigint') {
|
|
917
|
-
return `[BigInt: ${String(value)}]`;
|
|
918
|
-
}
|
|
919
|
-
return value;
|
|
920
|
-
}
|
|
921
|
-
/**
|
|
922
|
-
* Walks an object to perform a normalization on it
|
|
923
|
-
*
|
|
924
|
-
* @param key of object that's walked in current iteration
|
|
925
|
-
* @param value object to be walked
|
|
926
|
-
* @param depth Optional number indicating how deep should walking be performed
|
|
927
|
-
* @param maxProperties Optional maximum number of properties/elements included in any single object/array
|
|
928
|
-
* @param memo Optional Memo class handling decycling
|
|
929
|
-
*/
|
|
930
|
-
function walk(key, value, depth = +Infinity, maxProperties = +Infinity, memo = memoBuilder()) {
|
|
931
|
-
const [memoize, unmemoize] = memo;
|
|
932
|
-
// If we reach the maximum depth, serialize whatever is left
|
|
933
|
-
if (depth === 0) {
|
|
934
|
-
return serializeValue(value);
|
|
935
|
-
}
|
|
936
|
-
// If value implements `toJSON` method, call it and return early
|
|
937
|
-
if (value !== null && value !== undefined && typeof value.toJSON === 'function') {
|
|
938
|
-
return value.toJSON();
|
|
939
|
-
}
|
|
940
|
-
// `makeSerializable` provides a string representation of certain non-serializable values. For all others, it's a
|
|
941
|
-
// pass-through. If what comes back is a primitive (either because it's been stringified or because it was primitive
|
|
942
|
-
// all along), we're done.
|
|
943
|
-
const serializable = makeSerializable(value, key);
|
|
944
|
-
if (isPrimitive(serializable)) {
|
|
945
|
-
return serializable;
|
|
946
|
-
}
|
|
947
|
-
// Create source that we will use for the next iteration. It will either be an objectified error object (`Error` type
|
|
948
|
-
// with extracted key:value pairs) or the input itself.
|
|
949
|
-
const source = getWalkSource(value);
|
|
950
|
-
// Create an accumulator that will act as a parent for all future itterations of that branch
|
|
951
|
-
const acc = Array.isArray(value) ? [] : {};
|
|
952
|
-
// If we already walked that branch, bail out, as it's circular reference
|
|
953
|
-
if (memoize(value)) {
|
|
954
|
-
return '[Circular ~]';
|
|
955
|
-
}
|
|
956
|
-
let propertyCount = 0;
|
|
957
|
-
// Walk all keys of the source
|
|
958
|
-
for (const innerKey in source) {
|
|
959
|
-
// Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.
|
|
960
|
-
if (!Object.prototype.hasOwnProperty.call(source, innerKey)) {
|
|
961
|
-
continue;
|
|
962
|
-
}
|
|
963
|
-
if (propertyCount >= maxProperties) {
|
|
964
|
-
acc[innerKey] = '[MaxProperties ~]';
|
|
965
|
-
break;
|
|
966
|
-
}
|
|
967
|
-
propertyCount += 1;
|
|
968
|
-
// Recursively walk through all the child nodes
|
|
969
|
-
const innerValue = source[innerKey];
|
|
970
|
-
acc[innerKey] = walk(innerKey, innerValue, depth - 1, maxProperties, memo);
|
|
971
|
-
}
|
|
972
|
-
// Once walked through all the branches, remove the parent from memo storage
|
|
973
|
-
unmemoize(value);
|
|
974
|
-
// Return accumulated values
|
|
975
|
-
return acc;
|
|
976
|
-
}
|
|
977
|
-
/**
|
|
978
|
-
* Recursively normalizes the given object.
|
|
979
|
-
*
|
|
980
|
-
* - Creates a copy to prevent original input mutation
|
|
981
|
-
* - Skips non-enumerable properties
|
|
982
|
-
* - When stringifying, calls `toJSON` if implemented
|
|
983
|
-
* - Removes circular references
|
|
984
|
-
* - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format
|
|
985
|
-
* - Translates known global objects/classes to a string representations
|
|
986
|
-
* - Takes care of `Error` object serialization
|
|
987
|
-
* - Optionally limits depth of final output
|
|
988
|
-
* - Optionally limits number of properties/elements included in any single object/array
|
|
989
|
-
*
|
|
990
|
-
* @param input The object to be normalized.
|
|
991
|
-
* @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)
|
|
992
|
-
* @param maxProperties The max number of elements or properties to be included in any single array or
|
|
993
|
-
* object in the normallized output..
|
|
994
|
-
* @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization.
|
|
995
|
-
*/
|
|
996
|
-
function normalize(input, depth = +Infinity, maxProperties = +Infinity) {
|
|
997
|
-
try {
|
|
998
|
-
// since we're at the outermost level, there is no key
|
|
999
|
-
return walk('', input, depth, maxProperties);
|
|
1000
|
-
}
|
|
1001
|
-
catch (_oO) {
|
|
1002
|
-
return '**non-serializable**';
|
|
684
|
+
const source = {};
|
|
685
|
+
// Accessing event attributes can throw (see https://github.com/getsentry/sentry-javascript/issues/768 and
|
|
686
|
+
// https://github.com/getsentry/sentry-javascript/issues/838), but accessing `type` hasn't been wrapped in a
|
|
687
|
+
// try-catch in at least two years and no one's complained, so that's likely not an issue anymore
|
|
688
|
+
source.type = event.type;
|
|
689
|
+
try {
|
|
690
|
+
source.target = isElement(event.target)
|
|
691
|
+
? htmlTreeAsString(event.target)
|
|
692
|
+
: Object.prototype.toString.call(event.target);
|
|
693
|
+
}
|
|
694
|
+
catch (_oO) {
|
|
695
|
+
source.target = '<unknown>';
|
|
696
|
+
}
|
|
697
|
+
try {
|
|
698
|
+
source.currentTarget = isElement(event.currentTarget)
|
|
699
|
+
? htmlTreeAsString(event.currentTarget)
|
|
700
|
+
: Object.prototype.toString.call(event.currentTarget);
|
|
701
|
+
}
|
|
702
|
+
catch (_oO) {
|
|
703
|
+
source.currentTarget = '<unknown>';
|
|
704
|
+
}
|
|
705
|
+
if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {
|
|
706
|
+
source.detail = event.detail;
|
|
707
|
+
}
|
|
708
|
+
for (const attr in event) {
|
|
709
|
+
if (Object.prototype.hasOwnProperty.call(event, attr)) {
|
|
710
|
+
source[attr] = event[attr];
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return source;
|
|
1003
714
|
}
|
|
715
|
+
return value;
|
|
1004
716
|
}
|
|
1005
717
|
/**
|
|
1006
718
|
* Given any captured exception, extract its keys and create a sorted
|
|
@@ -1050,6 +762,72 @@ var Sentry = (function (exports) {
|
|
|
1050
762
|
return val;
|
|
1051
763
|
}
|
|
1052
764
|
|
|
765
|
+
const STACKTRACE_LIMIT = 50;
|
|
766
|
+
/**
|
|
767
|
+
* Creates a stack parser with the supplied line parsers
|
|
768
|
+
*
|
|
769
|
+
* StackFrames are returned in the correct order for Sentry Exception
|
|
770
|
+
* frames and with Sentry SDK internal frames removed from the top and bottom
|
|
771
|
+
*
|
|
772
|
+
*/
|
|
773
|
+
function createStackParser(...parsers) {
|
|
774
|
+
const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);
|
|
775
|
+
return (stack, skipFirst = 0) => {
|
|
776
|
+
const frames = [];
|
|
777
|
+
for (const line of stack.split('\n').slice(skipFirst)) {
|
|
778
|
+
for (const parser of sortedParsers) {
|
|
779
|
+
const frame = parser(line);
|
|
780
|
+
if (frame) {
|
|
781
|
+
frames.push(frame);
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return stripSentryFramesAndReverse(frames);
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* @hidden
|
|
791
|
+
*/
|
|
792
|
+
function stripSentryFramesAndReverse(stack) {
|
|
793
|
+
if (!stack.length) {
|
|
794
|
+
return [];
|
|
795
|
+
}
|
|
796
|
+
let localStack = stack;
|
|
797
|
+
const firstFrameFunction = localStack[0].function || '';
|
|
798
|
+
const lastFrameFunction = localStack[localStack.length - 1].function || '';
|
|
799
|
+
// If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
|
|
800
|
+
if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
|
|
801
|
+
localStack = localStack.slice(1);
|
|
802
|
+
}
|
|
803
|
+
// If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)
|
|
804
|
+
if (lastFrameFunction.indexOf('sentryWrapped') !== -1) {
|
|
805
|
+
localStack = localStack.slice(0, -1);
|
|
806
|
+
}
|
|
807
|
+
// The frame where the crash happened, should be the last entry in the array
|
|
808
|
+
return localStack
|
|
809
|
+
.slice(0, STACKTRACE_LIMIT)
|
|
810
|
+
.map(frame => (Object.assign(Object.assign({}, frame), { filename: frame.filename || localStack[0].filename, function: frame.function || '?' })))
|
|
811
|
+
.reverse();
|
|
812
|
+
}
|
|
813
|
+
const defaultFunctionName = '<anonymous>';
|
|
814
|
+
/**
|
|
815
|
+
* Safely extract function name from itself
|
|
816
|
+
*/
|
|
817
|
+
function getFunctionName(fn) {
|
|
818
|
+
try {
|
|
819
|
+
if (!fn || typeof fn !== 'function') {
|
|
820
|
+
return defaultFunctionName;
|
|
821
|
+
}
|
|
822
|
+
return fn.name || defaultFunctionName;
|
|
823
|
+
}
|
|
824
|
+
catch (e) {
|
|
825
|
+
// Just accessing custom props in some Selenium environments
|
|
826
|
+
// can cause a "Permission denied" exception (see raven-js#495).
|
|
827
|
+
return defaultFunctionName;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
1053
831
|
/**
|
|
1054
832
|
* Tells whether current environment supports Fetch API
|
|
1055
833
|
* {@link supportsFetch}.
|
|
@@ -1632,6 +1410,48 @@ var Sentry = (function (exports) {
|
|
|
1632
1410
|
};
|
|
1633
1411
|
}
|
|
1634
1412
|
|
|
1413
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
1414
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1415
|
+
/**
|
|
1416
|
+
* Helper to decycle json objects
|
|
1417
|
+
*/
|
|
1418
|
+
function memoBuilder() {
|
|
1419
|
+
const hasWeakSet = typeof WeakSet === 'function';
|
|
1420
|
+
const inner = hasWeakSet ? new WeakSet() : [];
|
|
1421
|
+
function memoize(obj) {
|
|
1422
|
+
if (hasWeakSet) {
|
|
1423
|
+
if (inner.has(obj)) {
|
|
1424
|
+
return true;
|
|
1425
|
+
}
|
|
1426
|
+
inner.add(obj);
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
1430
|
+
for (let i = 0; i < inner.length; i++) {
|
|
1431
|
+
const value = inner[i];
|
|
1432
|
+
if (value === obj) {
|
|
1433
|
+
return true;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
inner.push(obj);
|
|
1437
|
+
return false;
|
|
1438
|
+
}
|
|
1439
|
+
function unmemoize(obj) {
|
|
1440
|
+
if (hasWeakSet) {
|
|
1441
|
+
inner.delete(obj);
|
|
1442
|
+
}
|
|
1443
|
+
else {
|
|
1444
|
+
for (let i = 0; i < inner.length; i++) {
|
|
1445
|
+
if (inner[i] === obj) {
|
|
1446
|
+
inner.splice(i, 1);
|
|
1447
|
+
break;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
return [memoize, unmemoize];
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1635
1455
|
/**
|
|
1636
1456
|
* UUID4 generator
|
|
1637
1457
|
*
|
|
@@ -1721,72 +1541,253 @@ var Sentry = (function (exports) {
|
|
|
1721
1541
|
* @param type Type of the exception.
|
|
1722
1542
|
* @hidden
|
|
1723
1543
|
*/
|
|
1724
|
-
function addExceptionTypeValue(event, value, type) {
|
|
1725
|
-
const exception = (event.exception = event.exception || {});
|
|
1726
|
-
const values = (exception.values = exception.values || []);
|
|
1727
|
-
const firstException = (values[0] = values[0] || {});
|
|
1728
|
-
if (!firstException.value) {
|
|
1729
|
-
firstException.value = value || '';
|
|
1544
|
+
function addExceptionTypeValue(event, value, type) {
|
|
1545
|
+
const exception = (event.exception = event.exception || {});
|
|
1546
|
+
const values = (exception.values = exception.values || []);
|
|
1547
|
+
const firstException = (values[0] = values[0] || {});
|
|
1548
|
+
if (!firstException.value) {
|
|
1549
|
+
firstException.value = value || '';
|
|
1550
|
+
}
|
|
1551
|
+
if (!firstException.type) {
|
|
1552
|
+
firstException.type = type || 'Error';
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
|
|
1557
|
+
*
|
|
1558
|
+
* @param event The event to modify.
|
|
1559
|
+
* @param newMechanism Mechanism data to add to the event.
|
|
1560
|
+
* @hidden
|
|
1561
|
+
*/
|
|
1562
|
+
function addExceptionMechanism(event, newMechanism) {
|
|
1563
|
+
const firstException = getFirstException(event);
|
|
1564
|
+
if (!firstException) {
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
const defaultMechanism = { type: 'generic', handled: true };
|
|
1568
|
+
const currentMechanism = firstException.mechanism;
|
|
1569
|
+
firstException.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
|
|
1570
|
+
if (newMechanism && 'data' in newMechanism) {
|
|
1571
|
+
const mergedData = Object.assign(Object.assign({}, (currentMechanism && currentMechanism.data)), newMechanism.data);
|
|
1572
|
+
firstException.mechanism.data = mergedData;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
|
|
1577
|
+
* in question), and marks it captured if not.
|
|
1578
|
+
*
|
|
1579
|
+
* This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
|
|
1580
|
+
* record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
|
|
1581
|
+
* that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
|
|
1582
|
+
* the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
|
|
1583
|
+
* caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
|
|
1584
|
+
* function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
|
|
1585
|
+
* see it.
|
|
1586
|
+
*
|
|
1587
|
+
* Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
|
|
1588
|
+
* them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
|
|
1589
|
+
* object wrapper forms so that this check will always work. However, because we need to flag the exact object which
|
|
1590
|
+
* will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
|
|
1591
|
+
* must be done before the exception captured.
|
|
1592
|
+
*
|
|
1593
|
+
* @param A thrown exception to check or flag as having been seen
|
|
1594
|
+
* @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
|
|
1595
|
+
*/
|
|
1596
|
+
function checkOrSetAlreadyCaught(exception) {
|
|
1597
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1598
|
+
if (exception && exception.__sentry_captured__) {
|
|
1599
|
+
return true;
|
|
1600
|
+
}
|
|
1601
|
+
try {
|
|
1602
|
+
// set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
|
|
1603
|
+
// `ExtraErrorData` integration
|
|
1604
|
+
addNonEnumerableProperty(exception, '__sentry_captured__', true);
|
|
1605
|
+
}
|
|
1606
|
+
catch (err) {
|
|
1607
|
+
// `exception` is a primitive, so we can't mark it seen
|
|
1608
|
+
}
|
|
1609
|
+
return false;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Recursively normalizes the given object.
|
|
1614
|
+
*
|
|
1615
|
+
* - Creates a copy to prevent original input mutation
|
|
1616
|
+
* - Skips non-enumerable properties
|
|
1617
|
+
* - When stringifying, calls `toJSON` if implemented
|
|
1618
|
+
* - Removes circular references
|
|
1619
|
+
* - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format
|
|
1620
|
+
* - Translates known global objects/classes to a string representations
|
|
1621
|
+
* - Takes care of `Error` object serialization
|
|
1622
|
+
* - Optionally limits depth of final output
|
|
1623
|
+
* - Optionally limits number of properties/elements included in any single object/array
|
|
1624
|
+
*
|
|
1625
|
+
* @param input The object to be normalized.
|
|
1626
|
+
* @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)
|
|
1627
|
+
* @param maxProperties The max number of elements or properties to be included in any single array or
|
|
1628
|
+
* object in the normallized output..
|
|
1629
|
+
* @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization.
|
|
1630
|
+
*/
|
|
1631
|
+
function normalize(input, depth = +Infinity, maxProperties = +Infinity) {
|
|
1632
|
+
try {
|
|
1633
|
+
// since we're at the outermost level, there is no key
|
|
1634
|
+
return walk('', input, depth, maxProperties);
|
|
1635
|
+
}
|
|
1636
|
+
catch (_oO) {
|
|
1637
|
+
return '**non-serializable**';
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
/** JSDoc */
|
|
1641
|
+
function normalizeToSize(object,
|
|
1642
|
+
// Default Node.js REPL depth
|
|
1643
|
+
depth = 3,
|
|
1644
|
+
// 100kB, as 200kB is max payload size, so half sounds reasonable
|
|
1645
|
+
maxSize = 100 * 1024) {
|
|
1646
|
+
const serialized = normalize(object, depth);
|
|
1647
|
+
if (jsonSize(serialized) > maxSize) {
|
|
1648
|
+
return normalizeToSize(object, depth - 1, maxSize);
|
|
1649
|
+
}
|
|
1650
|
+
return serialized;
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Walks an object to perform a normalization on it
|
|
1654
|
+
*
|
|
1655
|
+
* @param key of object that's walked in current iteration
|
|
1656
|
+
* @param value object to be walked
|
|
1657
|
+
* @param depth Optional number indicating how deep should walking be performed
|
|
1658
|
+
* @param maxProperties Optional maximum number of properties/elements included in any single object/array
|
|
1659
|
+
* @param memo Optional Memo class handling decycling
|
|
1660
|
+
*/
|
|
1661
|
+
function walk(key, value, depth = +Infinity, maxProperties = +Infinity, memo = memoBuilder()) {
|
|
1662
|
+
const [memoize, unmemoize] = memo;
|
|
1663
|
+
// If we reach the maximum depth, serialize whatever is left
|
|
1664
|
+
if (depth === 0) {
|
|
1665
|
+
return serializeValue(value);
|
|
1730
1666
|
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1667
|
+
// If value implements `toJSON` method, call it and return early
|
|
1668
|
+
if (value !== null && value !== undefined && typeof value.toJSON === 'function') {
|
|
1669
|
+
return value.toJSON();
|
|
1670
|
+
}
|
|
1671
|
+
// `makeSerializable` provides a string representation of certain non-serializable values. For all others, it's a
|
|
1672
|
+
// pass-through. If what comes back is a primitive (either because it's been stringified or because it was primitive
|
|
1673
|
+
// all along), we're done.
|
|
1674
|
+
const serializable = makeSerializable(value, key);
|
|
1675
|
+
if (isPrimitive(serializable)) {
|
|
1676
|
+
return serializable;
|
|
1677
|
+
}
|
|
1678
|
+
// Create source that we will use for the next iteration. It will either be an objectified error object (`Error` type
|
|
1679
|
+
// with extracted key:value pairs) or the input itself.
|
|
1680
|
+
const source = getWalkSource(value);
|
|
1681
|
+
// Create an accumulator that will act as a parent for all future itterations of that branch
|
|
1682
|
+
const acc = Array.isArray(value) ? [] : {};
|
|
1683
|
+
// If we already walked that branch, bail out, as it's circular reference
|
|
1684
|
+
if (memoize(value)) {
|
|
1685
|
+
return '[Circular ~]';
|
|
1733
1686
|
}
|
|
1687
|
+
let propertyCount = 0;
|
|
1688
|
+
// Walk all keys of the source
|
|
1689
|
+
for (const innerKey in source) {
|
|
1690
|
+
// Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.
|
|
1691
|
+
if (!Object.prototype.hasOwnProperty.call(source, innerKey)) {
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
if (propertyCount >= maxProperties) {
|
|
1695
|
+
acc[innerKey] = '[MaxProperties ~]';
|
|
1696
|
+
break;
|
|
1697
|
+
}
|
|
1698
|
+
propertyCount += 1;
|
|
1699
|
+
// Recursively walk through all the child nodes
|
|
1700
|
+
const innerValue = source[innerKey];
|
|
1701
|
+
acc[innerKey] = walk(innerKey, innerValue, depth - 1, maxProperties, memo);
|
|
1702
|
+
}
|
|
1703
|
+
// Once walked through all the branches, remove the parent from memo storage
|
|
1704
|
+
unmemoize(value);
|
|
1705
|
+
// Return accumulated values
|
|
1706
|
+
return acc;
|
|
1734
1707
|
}
|
|
1735
1708
|
/**
|
|
1736
|
-
*
|
|
1709
|
+
* Transform any non-primitive, BigInt, or Symbol-type value into a string. Acts as a no-op on strings, numbers,
|
|
1710
|
+
* booleans, null, and undefined.
|
|
1737
1711
|
*
|
|
1738
|
-
* @param
|
|
1739
|
-
* @
|
|
1740
|
-
*
|
|
1712
|
+
* @param value The value to stringify
|
|
1713
|
+
* @returns For non-primitive, BigInt, and Symbol-type values, a string denoting the value's type, type and value, or
|
|
1714
|
+
* type and `description` property, respectively. For non-BigInt, non-Symbol primitives, returns the original value,
|
|
1715
|
+
* unchanged.
|
|
1741
1716
|
*/
|
|
1742
|
-
function
|
|
1743
|
-
|
|
1744
|
-
if (
|
|
1745
|
-
return;
|
|
1717
|
+
function serializeValue(value) {
|
|
1718
|
+
// Node.js REPL notation
|
|
1719
|
+
if (typeof value === 'string') {
|
|
1720
|
+
return value;
|
|
1746
1721
|
}
|
|
1747
|
-
const
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1722
|
+
const type = Object.prototype.toString.call(value);
|
|
1723
|
+
if (type === '[object Object]') {
|
|
1724
|
+
return '[Object]';
|
|
1725
|
+
}
|
|
1726
|
+
if (type === '[object Array]') {
|
|
1727
|
+
return '[Array]';
|
|
1753
1728
|
}
|
|
1729
|
+
// `makeSerializable` provides a string representation of certain non-serializable values. For all others, it's a
|
|
1730
|
+
// pass-through.
|
|
1731
|
+
const serializable = makeSerializable(value);
|
|
1732
|
+
return isPrimitive(serializable) ? serializable : type;
|
|
1754
1733
|
}
|
|
1755
1734
|
/**
|
|
1756
|
-
*
|
|
1757
|
-
* in question), and marks it captured if not.
|
|
1758
|
-
*
|
|
1759
|
-
* This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
|
|
1760
|
-
* record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
|
|
1761
|
-
* that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
|
|
1762
|
-
* the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
|
|
1763
|
-
* caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
|
|
1764
|
-
* function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
|
|
1765
|
-
* see it.
|
|
1735
|
+
* makeSerializable()
|
|
1766
1736
|
*
|
|
1767
|
-
*
|
|
1768
|
-
* them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
|
|
1769
|
-
* object wrapper forms so that this check will always work. However, because we need to flag the exact object which
|
|
1770
|
-
* will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
|
|
1771
|
-
* must be done before the exception captured.
|
|
1737
|
+
* Takes unserializable input and make it serializer-friendly.
|
|
1772
1738
|
*
|
|
1773
|
-
*
|
|
1774
|
-
* @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
|
|
1739
|
+
* Handles globals, functions, `undefined`, `NaN`, and other non-serializable values.
|
|
1775
1740
|
*/
|
|
1776
|
-
function
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
return true;
|
|
1741
|
+
function makeSerializable(value, key) {
|
|
1742
|
+
if (key === 'domain' && value && typeof value === 'object' && value._events) {
|
|
1743
|
+
return '[Domain]';
|
|
1780
1744
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
// `ExtraErrorData` integration
|
|
1784
|
-
addNonEnumerableProperty(exception, '__sentry_captured__', true);
|
|
1745
|
+
if (key === 'domainEmitter') {
|
|
1746
|
+
return '[DomainEmitter]';
|
|
1785
1747
|
}
|
|
1786
|
-
|
|
1787
|
-
|
|
1748
|
+
if (typeof global !== 'undefined' && value === global) {
|
|
1749
|
+
return '[Global]';
|
|
1788
1750
|
}
|
|
1789
|
-
|
|
1751
|
+
// It's safe to use `window` and `document` here in this manner, as we are asserting using `typeof` first
|
|
1752
|
+
// which won't throw if they are not present.
|
|
1753
|
+
// eslint-disable-next-line no-restricted-globals
|
|
1754
|
+
if (typeof window !== 'undefined' && value === window) {
|
|
1755
|
+
return '[Window]';
|
|
1756
|
+
}
|
|
1757
|
+
// eslint-disable-next-line no-restricted-globals
|
|
1758
|
+
if (typeof document !== 'undefined' && value === document) {
|
|
1759
|
+
return '[Document]';
|
|
1760
|
+
}
|
|
1761
|
+
// React's SyntheticEvent thingy
|
|
1762
|
+
if (isSyntheticEvent(value)) {
|
|
1763
|
+
return '[SyntheticEvent]';
|
|
1764
|
+
}
|
|
1765
|
+
if (typeof value === 'number' && value !== value) {
|
|
1766
|
+
return '[NaN]';
|
|
1767
|
+
}
|
|
1768
|
+
if (value === void 0) {
|
|
1769
|
+
return '[undefined]';
|
|
1770
|
+
}
|
|
1771
|
+
if (typeof value === 'function') {
|
|
1772
|
+
return `[Function: ${getFunctionName(value)}]`;
|
|
1773
|
+
}
|
|
1774
|
+
// symbols and bigints are considered primitives by TS, but aren't natively JSON-serilaizable
|
|
1775
|
+
if (typeof value === 'symbol') {
|
|
1776
|
+
return `[${String(value)}]`;
|
|
1777
|
+
}
|
|
1778
|
+
if (typeof value === 'bigint') {
|
|
1779
|
+
return `[BigInt: ${String(value)}]`;
|
|
1780
|
+
}
|
|
1781
|
+
return value;
|
|
1782
|
+
}
|
|
1783
|
+
/** Calculates bytes size of input string */
|
|
1784
|
+
function utf8Length(value) {
|
|
1785
|
+
// eslint-disable-next-line no-bitwise
|
|
1786
|
+
return ~-encodeURI(value).split(/%..|./).length;
|
|
1787
|
+
}
|
|
1788
|
+
/** Calculates bytes size of input object */
|
|
1789
|
+
function jsonSize(value) {
|
|
1790
|
+
return utf8Length(JSON.stringify(value));
|
|
1790
1791
|
}
|
|
1791
1792
|
|
|
1792
1793
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
@@ -4059,126 +4060,47 @@ var Sentry = (function (exports) {
|
|
|
4059
4060
|
throw reason;
|
|
4060
4061
|
}
|
|
4061
4062
|
this.captureException(reason, {
|
|
4062
|
-
data: {
|
|
4063
|
-
__sentry__: true,
|
|
4064
|
-
},
|
|
4065
|
-
originalException: reason,
|
|
4066
|
-
});
|
|
4067
|
-
throw new SentryError(`Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`);
|
|
4068
|
-
});
|
|
4069
|
-
}
|
|
4070
|
-
/**
|
|
4071
|
-
* Occupies the client with processing and event
|
|
4072
|
-
*/
|
|
4073
|
-
_process(promise) {
|
|
4074
|
-
this._numProcessing += 1;
|
|
4075
|
-
void promise.then(value => {
|
|
4076
|
-
this._numProcessing -= 1;
|
|
4077
|
-
return value;
|
|
4078
|
-
}, reason => {
|
|
4079
|
-
this._numProcessing -= 1;
|
|
4080
|
-
return reason;
|
|
4081
|
-
});
|
|
4082
|
-
}
|
|
4083
|
-
}
|
|
4084
|
-
/**
|
|
4085
|
-
* Verifies that return value of configured `beforeSend` is of expected type.
|
|
4086
|
-
*/
|
|
4087
|
-
function _ensureBeforeSendRv(rv) {
|
|
4088
|
-
const nullErr = '`beforeSend` method has to return `null` or a valid event.';
|
|
4089
|
-
if (isThenable(rv)) {
|
|
4090
|
-
return rv.then(event => {
|
|
4091
|
-
if (!(isPlainObject(event) || event === null)) {
|
|
4092
|
-
throw new SentryError(nullErr);
|
|
4093
|
-
}
|
|
4094
|
-
return event;
|
|
4095
|
-
}, e => {
|
|
4096
|
-
throw new SentryError(`beforeSend rejected with ${e}`);
|
|
4097
|
-
});
|
|
4098
|
-
}
|
|
4099
|
-
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4100
|
-
throw new SentryError(nullErr);
|
|
4101
|
-
}
|
|
4102
|
-
return rv;
|
|
4103
|
-
}
|
|
4104
|
-
|
|
4105
|
-
/** Noop transport */
|
|
4106
|
-
class NoopTransport {
|
|
4107
|
-
/**
|
|
4108
|
-
* @inheritDoc
|
|
4109
|
-
*/
|
|
4110
|
-
sendEvent(_) {
|
|
4111
|
-
return resolvedSyncPromise({
|
|
4112
|
-
reason: 'NoopTransport: Event has been skipped because no Dsn is configured.',
|
|
4113
|
-
status: 'skipped',
|
|
4114
|
-
});
|
|
4115
|
-
}
|
|
4116
|
-
/**
|
|
4117
|
-
* @inheritDoc
|
|
4118
|
-
*/
|
|
4119
|
-
close(_) {
|
|
4120
|
-
return resolvedSyncPromise(true);
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
|
|
4124
|
-
/**
|
|
4125
|
-
* This is the base implemention of a Backend.
|
|
4126
|
-
* @hidden
|
|
4127
|
-
*/
|
|
4128
|
-
class BaseBackend {
|
|
4129
|
-
/** Creates a new backend instance. */
|
|
4130
|
-
constructor(options) {
|
|
4131
|
-
this._options = options;
|
|
4132
|
-
if (!this._options.dsn) {
|
|
4133
|
-
logger.warn('No DSN provided, backend will not do anything.');
|
|
4134
|
-
}
|
|
4135
|
-
this._transport = this._setupTransport();
|
|
4136
|
-
}
|
|
4137
|
-
/**
|
|
4138
|
-
* @inheritDoc
|
|
4139
|
-
*/
|
|
4140
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
4141
|
-
eventFromException(_exception, _hint) {
|
|
4142
|
-
throw new SentryError('Backend has to implement `eventFromException` method');
|
|
4143
|
-
}
|
|
4144
|
-
/**
|
|
4145
|
-
* @inheritDoc
|
|
4146
|
-
*/
|
|
4147
|
-
eventFromMessage(_message, _level, _hint) {
|
|
4148
|
-
throw new SentryError('Backend has to implement `eventFromMessage` method');
|
|
4149
|
-
}
|
|
4150
|
-
/**
|
|
4151
|
-
* @inheritDoc
|
|
4152
|
-
*/
|
|
4153
|
-
sendEvent(event) {
|
|
4154
|
-
void this._transport.sendEvent(event).then(null, reason => {
|
|
4155
|
-
logger.error('Error while sending event:', reason);
|
|
4063
|
+
data: {
|
|
4064
|
+
__sentry__: true,
|
|
4065
|
+
},
|
|
4066
|
+
originalException: reason,
|
|
4067
|
+
});
|
|
4068
|
+
throw new SentryError(`Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`);
|
|
4156
4069
|
});
|
|
4157
4070
|
}
|
|
4158
4071
|
/**
|
|
4159
|
-
*
|
|
4072
|
+
* Occupies the client with processing and event
|
|
4160
4073
|
*/
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4074
|
+
_process(promise) {
|
|
4075
|
+
this._numProcessing += 1;
|
|
4076
|
+
void promise.then(value => {
|
|
4077
|
+
this._numProcessing -= 1;
|
|
4078
|
+
return value;
|
|
4079
|
+
}, reason => {
|
|
4080
|
+
this._numProcessing -= 1;
|
|
4081
|
+
return reason;
|
|
4168
4082
|
});
|
|
4169
4083
|
}
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4084
|
+
}
|
|
4085
|
+
/**
|
|
4086
|
+
* Verifies that return value of configured `beforeSend` is of expected type.
|
|
4087
|
+
*/
|
|
4088
|
+
function _ensureBeforeSendRv(rv) {
|
|
4089
|
+
const nullErr = '`beforeSend` method has to return `null` or a valid event.';
|
|
4090
|
+
if (isThenable(rv)) {
|
|
4091
|
+
return rv.then(event => {
|
|
4092
|
+
if (!(isPlainObject(event) || event === null)) {
|
|
4093
|
+
throw new SentryError(nullErr);
|
|
4094
|
+
}
|
|
4095
|
+
return event;
|
|
4096
|
+
}, e => {
|
|
4097
|
+
throw new SentryError(`beforeSend rejected with ${e}`);
|
|
4098
|
+
});
|
|
4175
4099
|
}
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
*/
|
|
4179
|
-
_setupTransport() {
|
|
4180
|
-
return new NoopTransport();
|
|
4100
|
+
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4101
|
+
throw new SentryError(nullErr);
|
|
4181
4102
|
}
|
|
4103
|
+
return rv;
|
|
4182
4104
|
}
|
|
4183
4105
|
|
|
4184
4106
|
/** Extract sdk info from from the API metadata */
|
|
@@ -4204,8 +4126,8 @@ var Sentry = (function (exports) {
|
|
|
4204
4126
|
event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];
|
|
4205
4127
|
return event;
|
|
4206
4128
|
}
|
|
4207
|
-
/** Creates
|
|
4208
|
-
function
|
|
4129
|
+
/** Creates an envelope from a Session */
|
|
4130
|
+
function createSessionEnvelope(session, api) {
|
|
4209
4131
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4210
4132
|
const envelopeHeaders = Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) }));
|
|
4211
4133
|
// I know this is hacky but we don't want to add `sessions` to request type since it's never rate limited
|
|
@@ -4213,12 +4135,36 @@ var Sentry = (function (exports) {
|
|
|
4213
4135
|
// TODO (v7) Have to cast type because envelope items do not accept a `SentryRequestType`
|
|
4214
4136
|
const envelopeItem = [{ type }, session];
|
|
4215
4137
|
const envelope = createEnvelope(envelopeHeaders, [envelopeItem]);
|
|
4138
|
+
return [envelope, type];
|
|
4139
|
+
}
|
|
4140
|
+
/** Creates a SentryRequest from a Session. */
|
|
4141
|
+
function sessionToSentryRequest(session, api) {
|
|
4142
|
+
const [envelope, type] = createSessionEnvelope(session, api);
|
|
4216
4143
|
return {
|
|
4217
4144
|
body: serializeEnvelope(envelope),
|
|
4218
4145
|
type,
|
|
4219
4146
|
url: getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel),
|
|
4220
4147
|
};
|
|
4221
4148
|
}
|
|
4149
|
+
/**
|
|
4150
|
+
* Create an Envelope from an event. Note that this is duplicated from below,
|
|
4151
|
+
* but on purpose as this will be refactored in v7.
|
|
4152
|
+
*/
|
|
4153
|
+
function createEventEnvelope(event, api) {
|
|
4154
|
+
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4155
|
+
const eventType = event.type || 'event';
|
|
4156
|
+
const { transactionSampling } = event.sdkProcessingMetadata || {};
|
|
4157
|
+
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
|
|
4158
|
+
const envelopeHeaders = Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) }));
|
|
4159
|
+
const eventItem = [
|
|
4160
|
+
{
|
|
4161
|
+
type: eventType,
|
|
4162
|
+
sample_rates: [{ id: samplingMethod, rate: sampleRate }],
|
|
4163
|
+
},
|
|
4164
|
+
event,
|
|
4165
|
+
];
|
|
4166
|
+
return createEnvelope(envelopeHeaders, [eventItem]);
|
|
4167
|
+
}
|
|
4222
4168
|
/** Creates a SentryRequest from an event. */
|
|
4223
4169
|
function eventToSentryRequest(event, api) {
|
|
4224
4170
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
@@ -4306,6 +4252,111 @@ var Sentry = (function (exports) {
|
|
|
4306
4252
|
return req;
|
|
4307
4253
|
}
|
|
4308
4254
|
|
|
4255
|
+
/** Noop transport */
|
|
4256
|
+
class NoopTransport {
|
|
4257
|
+
/**
|
|
4258
|
+
* @inheritDoc
|
|
4259
|
+
*/
|
|
4260
|
+
sendEvent(_) {
|
|
4261
|
+
return resolvedSyncPromise({
|
|
4262
|
+
reason: 'NoopTransport: Event has been skipped because no Dsn is configured.',
|
|
4263
|
+
status: 'skipped',
|
|
4264
|
+
});
|
|
4265
|
+
}
|
|
4266
|
+
/**
|
|
4267
|
+
* @inheritDoc
|
|
4268
|
+
*/
|
|
4269
|
+
close(_) {
|
|
4270
|
+
return resolvedSyncPromise(true);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
|
|
4274
|
+
/**
|
|
4275
|
+
* This is the base implemention of a Backend.
|
|
4276
|
+
* @hidden
|
|
4277
|
+
*/
|
|
4278
|
+
class BaseBackend {
|
|
4279
|
+
/** Creates a new backend instance. */
|
|
4280
|
+
constructor(options) {
|
|
4281
|
+
this._options = options;
|
|
4282
|
+
if (!this._options.dsn) {
|
|
4283
|
+
logger.warn('No DSN provided, backend will not do anything.');
|
|
4284
|
+
}
|
|
4285
|
+
this._transport = this._setupTransport();
|
|
4286
|
+
}
|
|
4287
|
+
/**
|
|
4288
|
+
* @inheritDoc
|
|
4289
|
+
*/
|
|
4290
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
4291
|
+
eventFromException(_exception, _hint) {
|
|
4292
|
+
throw new SentryError('Backend has to implement `eventFromException` method');
|
|
4293
|
+
}
|
|
4294
|
+
/**
|
|
4295
|
+
* @inheritDoc
|
|
4296
|
+
*/
|
|
4297
|
+
eventFromMessage(_message, _level, _hint) {
|
|
4298
|
+
throw new SentryError('Backend has to implement `eventFromMessage` method');
|
|
4299
|
+
}
|
|
4300
|
+
/**
|
|
4301
|
+
* @inheritDoc
|
|
4302
|
+
*/
|
|
4303
|
+
sendEvent(event) {
|
|
4304
|
+
// TODO(v7): Remove the if-else
|
|
4305
|
+
if (this._newTransport &&
|
|
4306
|
+
this._options.dsn &&
|
|
4307
|
+
this._options._experiments &&
|
|
4308
|
+
this._options._experiments.newTransport) {
|
|
4309
|
+
const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel);
|
|
4310
|
+
const env = createEventEnvelope(event, api);
|
|
4311
|
+
void this._newTransport.send(env).then(null, reason => {
|
|
4312
|
+
logger.error('Error while sending event:', reason);
|
|
4313
|
+
});
|
|
4314
|
+
}
|
|
4315
|
+
else {
|
|
4316
|
+
void this._transport.sendEvent(event).then(null, reason => {
|
|
4317
|
+
logger.error('Error while sending event:', reason);
|
|
4318
|
+
});
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
/**
|
|
4322
|
+
* @inheritDoc
|
|
4323
|
+
*/
|
|
4324
|
+
sendSession(session) {
|
|
4325
|
+
if (!this._transport.sendSession) {
|
|
4326
|
+
logger.warn("Dropping session because custom transport doesn't implement sendSession");
|
|
4327
|
+
return;
|
|
4328
|
+
}
|
|
4329
|
+
// TODO(v7): Remove the if-else
|
|
4330
|
+
if (this._newTransport &&
|
|
4331
|
+
this._options.dsn &&
|
|
4332
|
+
this._options._experiments &&
|
|
4333
|
+
this._options._experiments.newTransport) {
|
|
4334
|
+
const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel);
|
|
4335
|
+
const [env] = createSessionEnvelope(session, api);
|
|
4336
|
+
void this._newTransport.send(env).then(null, reason => {
|
|
4337
|
+
logger.error('Error while sending session:', reason);
|
|
4338
|
+
});
|
|
4339
|
+
}
|
|
4340
|
+
else {
|
|
4341
|
+
void this._transport.sendSession(session).then(null, reason => {
|
|
4342
|
+
logger.error('Error while sending session:', reason);
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
/**
|
|
4347
|
+
* @inheritDoc
|
|
4348
|
+
*/
|
|
4349
|
+
getTransport() {
|
|
4350
|
+
return this._transport;
|
|
4351
|
+
}
|
|
4352
|
+
/**
|
|
4353
|
+
* Sets up the transport so it can be used later to send requests.
|
|
4354
|
+
*/
|
|
4355
|
+
_setupTransport() {
|
|
4356
|
+
return new NoopTransport();
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
|
|
4309
4360
|
/**
|
|
4310
4361
|
* Internal function to create a new SDK client instance. The client is
|
|
4311
4362
|
* installed and then bound to the current scope.
|
|
@@ -4328,7 +4379,7 @@ var Sentry = (function (exports) {
|
|
|
4328
4379
|
hub.bindClient(client);
|
|
4329
4380
|
}
|
|
4330
4381
|
|
|
4331
|
-
const SDK_VERSION = '6.19.
|
|
4382
|
+
const SDK_VERSION = '6.19.2';
|
|
4332
4383
|
|
|
4333
4384
|
let originalFunctionToString;
|
|
4334
4385
|
/** Patch toString calls to return proper name for wrapped functions */
|
|
@@ -4372,172 +4423,151 @@ var Sentry = (function (exports) {
|
|
|
4372
4423
|
/**
|
|
4373
4424
|
* @inheritDoc
|
|
4374
4425
|
*/
|
|
4375
|
-
setupOnce() {
|
|
4426
|
+
setupOnce(addGlobalEventProcessor, getCurrentHub) {
|
|
4376
4427
|
addGlobalEventProcessor((event) => {
|
|
4377
4428
|
const hub = getCurrentHub();
|
|
4378
|
-
if (
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
// This checks prevents most of the occurrences of the bug linked below:
|
|
4386
|
-
// https://github.com/getsentry/sentry-javascript/issues/2622
|
|
4387
|
-
// The bug is caused by multiple SDK instances, where one is minified and one is using non-mangled code.
|
|
4388
|
-
// Unfortunatelly we cannot fix it reliably (thus reserved property in rollup's terser config),
|
|
4389
|
-
// as we cannot force people using multiple instances in their apps to sync SDK versions.
|
|
4390
|
-
const options = typeof self._mergeOptions === 'function' ? self._mergeOptions(clientOptions) : {};
|
|
4391
|
-
if (typeof self._shouldDropEvent !== 'function') {
|
|
4392
|
-
return event;
|
|
4429
|
+
if (hub) {
|
|
4430
|
+
const self = hub.getIntegration(InboundFilters);
|
|
4431
|
+
if (self) {
|
|
4432
|
+
const client = hub.getClient();
|
|
4433
|
+
const clientOptions = client ? client.getOptions() : {};
|
|
4434
|
+
const options = _mergeOptions(self._options, clientOptions);
|
|
4435
|
+
return _shouldDropEvent$1(event, options) ? null : event;
|
|
4393
4436
|
}
|
|
4394
|
-
return self._shouldDropEvent(event, options) ? null : event;
|
|
4395
4437
|
}
|
|
4396
4438
|
return event;
|
|
4397
4439
|
});
|
|
4398
4440
|
}
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4441
|
+
}
|
|
4442
|
+
/**
|
|
4443
|
+
* @inheritDoc
|
|
4444
|
+
*/
|
|
4445
|
+
InboundFilters.id = 'InboundFilters';
|
|
4446
|
+
/** JSDoc */
|
|
4447
|
+
function _mergeOptions(internalOptions = {}, clientOptions = {}) {
|
|
4448
|
+
return {
|
|
4449
|
+
allowUrls: [
|
|
4450
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
4451
|
+
...(internalOptions.whitelistUrls || []),
|
|
4452
|
+
...(internalOptions.allowUrls || []),
|
|
4453
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
4454
|
+
...(clientOptions.whitelistUrls || []),
|
|
4455
|
+
...(clientOptions.allowUrls || []),
|
|
4456
|
+
],
|
|
4457
|
+
denyUrls: [
|
|
4458
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
4459
|
+
...(internalOptions.blacklistUrls || []),
|
|
4460
|
+
...(internalOptions.denyUrls || []),
|
|
4461
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
4462
|
+
...(clientOptions.blacklistUrls || []),
|
|
4463
|
+
...(clientOptions.denyUrls || []),
|
|
4464
|
+
],
|
|
4465
|
+
ignoreErrors: [
|
|
4466
|
+
...(internalOptions.ignoreErrors || []),
|
|
4467
|
+
...(clientOptions.ignoreErrors || []),
|
|
4468
|
+
...DEFAULT_IGNORE_ERRORS,
|
|
4469
|
+
],
|
|
4470
|
+
ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,
|
|
4471
|
+
};
|
|
4472
|
+
}
|
|
4473
|
+
/** JSDoc */
|
|
4474
|
+
function _shouldDropEvent$1(event, options) {
|
|
4475
|
+
if (options.ignoreInternal && _isSentryError(event)) {
|
|
4476
|
+
logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
|
|
4477
|
+
return true;
|
|
4478
|
+
}
|
|
4479
|
+
if (_isIgnoredError(event, options.ignoreErrors)) {
|
|
4480
|
+
logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
|
|
4481
|
+
return true;
|
|
4482
|
+
}
|
|
4483
|
+
if (_isDeniedUrl(event, options.denyUrls)) {
|
|
4484
|
+
logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${_getEventFilterUrl(event)}`);
|
|
4485
|
+
return true;
|
|
4486
|
+
}
|
|
4487
|
+
if (!_isAllowedUrl(event, options.allowUrls)) {
|
|
4488
|
+
logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${_getEventFilterUrl(event)}`);
|
|
4489
|
+
return true;
|
|
4490
|
+
}
|
|
4491
|
+
return false;
|
|
4492
|
+
}
|
|
4493
|
+
function _isIgnoredError(event, ignoreErrors) {
|
|
4494
|
+
if (!ignoreErrors || !ignoreErrors.length) {
|
|
4417
4495
|
return false;
|
|
4418
4496
|
}
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
try {
|
|
4425
|
-
// @ts-ignore can't be a sentry error if undefined
|
|
4426
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
4427
|
-
return event.exception.values[0].type === 'SentryError';
|
|
4428
|
-
}
|
|
4429
|
-
catch (e) {
|
|
4430
|
-
// ignore
|
|
4431
|
-
}
|
|
4497
|
+
return _getPossibleEventMessages(event).some(message => ignoreErrors.some(pattern => isMatchingPattern(message, pattern)));
|
|
4498
|
+
}
|
|
4499
|
+
function _isDeniedUrl(event, denyUrls) {
|
|
4500
|
+
// TODO: Use Glob instead?
|
|
4501
|
+
if (!denyUrls || !denyUrls.length) {
|
|
4432
4502
|
return false;
|
|
4433
4503
|
}
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
options.ignoreErrors.some(pattern => isMatchingPattern(message, pattern)));
|
|
4504
|
+
const url = _getEventFilterUrl(event);
|
|
4505
|
+
return !url ? false : denyUrls.some(pattern => isMatchingPattern(url, pattern));
|
|
4506
|
+
}
|
|
4507
|
+
function _isAllowedUrl(event, allowUrls) {
|
|
4508
|
+
// TODO: Use Glob instead?
|
|
4509
|
+
if (!allowUrls || !allowUrls.length) {
|
|
4510
|
+
return true;
|
|
4442
4511
|
}
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
const url = this._getEventFilterUrl(event);
|
|
4450
|
-
return !url ? false : options.denyUrls.some(pattern => isMatchingPattern(url, pattern));
|
|
4512
|
+
const url = _getEventFilterUrl(event);
|
|
4513
|
+
return !url ? true : allowUrls.some(pattern => isMatchingPattern(url, pattern));
|
|
4514
|
+
}
|
|
4515
|
+
function _getPossibleEventMessages(event) {
|
|
4516
|
+
if (event.message) {
|
|
4517
|
+
return [event.message];
|
|
4451
4518
|
}
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4519
|
+
if (event.exception) {
|
|
4520
|
+
try {
|
|
4521
|
+
const { type = '', value = '' } = (event.exception.values && event.exception.values[0]) || {};
|
|
4522
|
+
return [`${value}`, `${type}: ${value}`];
|
|
4523
|
+
}
|
|
4524
|
+
catch (oO) {
|
|
4525
|
+
logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
|
|
4526
|
+
return [];
|
|
4457
4527
|
}
|
|
4458
|
-
const url = this._getEventFilterUrl(event);
|
|
4459
|
-
return !url ? true : options.allowUrls.some(pattern => isMatchingPattern(url, pattern));
|
|
4460
4528
|
}
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
4469
|
-
...(clientOptions.whitelistUrls || []),
|
|
4470
|
-
...(clientOptions.allowUrls || []),
|
|
4471
|
-
],
|
|
4472
|
-
denyUrls: [
|
|
4473
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
4474
|
-
...(this._options.blacklistUrls || []),
|
|
4475
|
-
...(this._options.denyUrls || []),
|
|
4476
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
4477
|
-
...(clientOptions.blacklistUrls || []),
|
|
4478
|
-
...(clientOptions.denyUrls || []),
|
|
4479
|
-
],
|
|
4480
|
-
ignoreErrors: [
|
|
4481
|
-
...(this._options.ignoreErrors || []),
|
|
4482
|
-
...(clientOptions.ignoreErrors || []),
|
|
4483
|
-
...DEFAULT_IGNORE_ERRORS,
|
|
4484
|
-
],
|
|
4485
|
-
ignoreInternal: typeof this._options.ignoreInternal !== 'undefined' ? this._options.ignoreInternal : true,
|
|
4486
|
-
};
|
|
4529
|
+
return [];
|
|
4530
|
+
}
|
|
4531
|
+
function _isSentryError(event) {
|
|
4532
|
+
try {
|
|
4533
|
+
// @ts-ignore can't be a sentry error if undefined
|
|
4534
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
4535
|
+
return event.exception.values[0].type === 'SentryError';
|
|
4487
4536
|
}
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
if (event.message) {
|
|
4491
|
-
return [event.message];
|
|
4492
|
-
}
|
|
4493
|
-
if (event.exception) {
|
|
4494
|
-
try {
|
|
4495
|
-
const { type = '', value = '' } = (event.exception.values && event.exception.values[0]) || {};
|
|
4496
|
-
return [`${value}`, `${type}: ${value}`];
|
|
4497
|
-
}
|
|
4498
|
-
catch (oO) {
|
|
4499
|
-
logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
|
|
4500
|
-
return [];
|
|
4501
|
-
}
|
|
4502
|
-
}
|
|
4503
|
-
return [];
|
|
4537
|
+
catch (e) {
|
|
4538
|
+
// ignore
|
|
4504
4539
|
}
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4540
|
+
return false;
|
|
4541
|
+
}
|
|
4542
|
+
function _getLastValidUrl(frames = []) {
|
|
4543
|
+
for (let i = frames.length - 1; i >= 0; i--) {
|
|
4544
|
+
const frame = frames[i];
|
|
4545
|
+
if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
|
|
4546
|
+
return frame.filename || null;
|
|
4512
4547
|
}
|
|
4513
|
-
return null;
|
|
4514
4548
|
}
|
|
4515
|
-
|
|
4516
|
-
|
|
4549
|
+
return null;
|
|
4550
|
+
}
|
|
4551
|
+
function _getEventFilterUrl(event) {
|
|
4552
|
+
try {
|
|
4553
|
+
if (event.stacktrace) {
|
|
4554
|
+
return _getLastValidUrl(event.stacktrace.frames);
|
|
4555
|
+
}
|
|
4556
|
+
let frames;
|
|
4517
4557
|
try {
|
|
4518
|
-
if
|
|
4519
|
-
|
|
4520
|
-
}
|
|
4521
|
-
let frames;
|
|
4522
|
-
try {
|
|
4523
|
-
// @ts-ignore we only care about frames if the whole thing here is defined
|
|
4524
|
-
frames = event.exception.values[0].stacktrace.frames;
|
|
4525
|
-
}
|
|
4526
|
-
catch (e) {
|
|
4527
|
-
// ignore
|
|
4528
|
-
}
|
|
4529
|
-
return frames ? this._getLastValidUrl(frames) : null;
|
|
4558
|
+
// @ts-ignore we only care about frames if the whole thing here is defined
|
|
4559
|
+
frames = event.exception.values[0].stacktrace.frames;
|
|
4530
4560
|
}
|
|
4531
|
-
catch (
|
|
4532
|
-
|
|
4533
|
-
return null;
|
|
4561
|
+
catch (e) {
|
|
4562
|
+
// ignore
|
|
4534
4563
|
}
|
|
4564
|
+
return frames ? _getLastValidUrl(frames) : null;
|
|
4535
4565
|
}
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4566
|
+
catch (oO) {
|
|
4567
|
+
logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
|
|
4568
|
+
return null;
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4541
4571
|
|
|
4542
4572
|
var CoreIntegrations = /*#__PURE__*/Object.freeze({
|
|
4543
4573
|
__proto__: null,
|