@sentry/browser 6.16.1 → 6.17.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/build/bundle.es6.js +1311 -1428
- package/build/bundle.es6.js.map +1 -1
- package/build/bundle.es6.min.js +2 -2
- package/build/bundle.es6.min.js.map +1 -1
- package/build/bundle.js +1350 -1483
- package/build/bundle.js.map +1 -1
- package/build/bundle.min.js +2 -2
- package/build/bundle.min.js.map +1 -1
- package/dist/eventbuilder.d.ts +2 -2
- package/dist/eventbuilder.d.ts.map +1 -1
- package/dist/eventbuilder.js +7 -7
- package/dist/eventbuilder.js.map +1 -1
- package/dist/exports.d.ts +1 -1
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +0 -1
- package/dist/exports.js.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +26 -37
- package/dist/helpers.js.map +1 -1
- package/dist/integrations/breadcrumbs.d.ts +0 -20
- package/dist/integrations/breadcrumbs.d.ts.map +1 -1
- package/dist/integrations/breadcrumbs.js +132 -173
- package/dist/integrations/breadcrumbs.js.map +1 -1
- package/dist/integrations/dedupe.d.ts +0 -14
- package/dist/integrations/dedupe.d.ts.map +1 -1
- package/dist/integrations/dedupe.js +126 -126
- package/dist/integrations/dedupe.js.map +1 -1
- package/dist/integrations/globalhandlers.d.ts +7 -25
- package/dist/integrations/globalhandlers.d.ts.map +1 -1
- package/dist/integrations/globalhandlers.js +176 -168
- package/dist/integrations/globalhandlers.js.map +1 -1
- package/dist/integrations/linkederrors.d.ts +15 -13
- package/dist/integrations/linkederrors.d.ts.map +1 -1
- package/dist/integrations/linkederrors.js +26 -28
- package/dist/integrations/linkederrors.js.map +1 -1
- package/dist/integrations/trycatch.d.ts +0 -8
- package/dist/integrations/trycatch.d.ts.map +1 -1
- package/dist/integrations/trycatch.js +154 -153
- package/dist/integrations/trycatch.js.map +1 -1
- package/dist/integrations/useragent.js +2 -3
- package/dist/integrations/useragent.js.map +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +23 -19
- package/dist/sdk.js.map +1 -1
- package/dist/transports/base.d.ts +9 -4
- package/dist/transports/base.d.ts.map +1 -1
- package/dist/transports/base.js +23 -19
- package/dist/transports/base.js.map +1 -1
- package/dist/transports/fetch.d.ts +2 -10
- package/dist/transports/fetch.d.ts.map +1 -1
- package/dist/transports/fetch.js +6 -20
- package/dist/transports/fetch.js.map +1 -1
- package/dist/transports/utils.d.ts.map +1 -1
- package/dist/transports/utils.js +7 -5
- package/dist/transports/utils.js.map +1 -1
- package/dist/transports/xhr.d.ts +2 -10
- package/dist/transports/xhr.d.ts.map +1 -1
- package/dist/transports/xhr.js +3 -17
- package/dist/transports/xhr.js.map +1 -1
- package/esm/eventbuilder.d.ts +2 -2
- package/esm/eventbuilder.d.ts.map +1 -1
- package/esm/eventbuilder.js +8 -8
- package/esm/eventbuilder.js.map +1 -1
- package/esm/exports.d.ts +1 -1
- package/esm/exports.d.ts.map +1 -1
- package/esm/exports.js +1 -1
- package/esm/exports.js.map +1 -1
- package/esm/helpers.d.ts.map +1 -1
- package/esm/helpers.js +28 -39
- package/esm/helpers.js.map +1 -1
- package/esm/integrations/breadcrumbs.d.ts +0 -20
- package/esm/integrations/breadcrumbs.d.ts.map +1 -1
- package/esm/integrations/breadcrumbs.js +134 -175
- package/esm/integrations/breadcrumbs.js.map +1 -1
- package/esm/integrations/dedupe.d.ts +0 -14
- package/esm/integrations/dedupe.d.ts.map +1 -1
- package/esm/integrations/dedupe.js +126 -126
- package/esm/integrations/dedupe.js.map +1 -1
- package/esm/integrations/globalhandlers.d.ts +7 -25
- package/esm/integrations/globalhandlers.d.ts.map +1 -1
- package/esm/integrations/globalhandlers.js +178 -170
- package/esm/integrations/globalhandlers.js.map +1 -1
- package/esm/integrations/linkederrors.d.ts +15 -13
- package/esm/integrations/linkederrors.d.ts.map +1 -1
- package/esm/integrations/linkederrors.js +24 -28
- package/esm/integrations/linkederrors.js.map +1 -1
- package/esm/integrations/trycatch.d.ts +0 -8
- package/esm/integrations/trycatch.d.ts.map +1 -1
- package/esm/integrations/trycatch.js +155 -154
- package/esm/integrations/trycatch.js.map +1 -1
- package/esm/integrations/useragent.js +2 -3
- package/esm/integrations/useragent.js.map +1 -1
- package/esm/sdk.d.ts.map +1 -1
- package/esm/sdk.js +24 -20
- package/esm/sdk.js.map +1 -1
- package/esm/transports/base.d.ts +9 -4
- package/esm/transports/base.d.ts.map +1 -1
- package/esm/transports/base.js +25 -21
- package/esm/transports/base.js.map +1 -1
- package/esm/transports/fetch.d.ts +2 -10
- package/esm/transports/fetch.d.ts.map +1 -1
- package/esm/transports/fetch.js +6 -20
- package/esm/transports/fetch.js.map +1 -1
- package/esm/transports/utils.d.ts.map +1 -1
- package/esm/transports/utils.js +8 -6
- package/esm/transports/utils.js.map +1 -1
- package/esm/transports/xhr.d.ts +2 -10
- package/esm/transports/xhr.d.ts.map +1 -1
- package/esm/transports/xhr.js +3 -17
- package/esm/transports/xhr.js.map +1 -1
- package/package.json +4 -5
package/build/bundle.es6.js
CHANGED
|
@@ -1,43 +1,8 @@
|
|
|
1
|
-
/*! @sentry/browser 6.
|
|
1
|
+
/*! @sentry/browser 6.17.2 (37b1213) | https://github.com/getsentry/sentry-javascript */
|
|
2
2
|
var Sentry = (function (exports) {
|
|
3
|
-
/** Console logging verbosity for the SDK. */
|
|
4
|
-
var LogLevel;
|
|
5
|
-
(function (LogLevel) {
|
|
6
|
-
/** No logs will be generated. */
|
|
7
|
-
LogLevel[LogLevel["None"] = 0] = "None";
|
|
8
|
-
/** Only SDK internal errors will be logged. */
|
|
9
|
-
LogLevel[LogLevel["Error"] = 1] = "Error";
|
|
10
|
-
/** Information useful for debugging the SDK will be logged. */
|
|
11
|
-
LogLevel[LogLevel["Debug"] = 2] = "Debug";
|
|
12
|
-
/** All SDK actions will be logged. */
|
|
13
|
-
LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
|
|
14
|
-
})(LogLevel || (LogLevel = {}));
|
|
15
|
-
|
|
16
3
|
/**
|
|
17
|
-
*
|
|
4
|
+
* TODO(v7): Remove this enum and replace with SeverityLevel
|
|
18
5
|
*/
|
|
19
|
-
var SessionStatus;
|
|
20
|
-
(function (SessionStatus) {
|
|
21
|
-
/** JSDoc */
|
|
22
|
-
SessionStatus["Ok"] = "ok";
|
|
23
|
-
/** JSDoc */
|
|
24
|
-
SessionStatus["Exited"] = "exited";
|
|
25
|
-
/** JSDoc */
|
|
26
|
-
SessionStatus["Crashed"] = "crashed";
|
|
27
|
-
/** JSDoc */
|
|
28
|
-
SessionStatus["Abnormal"] = "abnormal";
|
|
29
|
-
})(SessionStatus || (SessionStatus = {}));
|
|
30
|
-
var RequestSessionStatus;
|
|
31
|
-
(function (RequestSessionStatus) {
|
|
32
|
-
/** JSDoc */
|
|
33
|
-
RequestSessionStatus["Ok"] = "ok";
|
|
34
|
-
/** JSDoc */
|
|
35
|
-
RequestSessionStatus["Errored"] = "errored";
|
|
36
|
-
/** JSDoc */
|
|
37
|
-
RequestSessionStatus["Crashed"] = "crashed";
|
|
38
|
-
})(RequestSessionStatus || (RequestSessionStatus = {}));
|
|
39
|
-
|
|
40
|
-
/** JSDoc */
|
|
41
6
|
(function (Severity) {
|
|
42
7
|
/** JSDoc */
|
|
43
8
|
Severity["Fatal"] = "fatal";
|
|
@@ -54,95 +19,7 @@ var Sentry = (function (exports) {
|
|
|
54
19
|
/** JSDoc */
|
|
55
20
|
Severity["Critical"] = "critical";
|
|
56
21
|
})(exports.Severity || (exports.Severity = {}));
|
|
57
|
-
|
|
58
|
-
(function (Severity) {
|
|
59
|
-
/**
|
|
60
|
-
* Converts a string-based level into a {@link Severity}.
|
|
61
|
-
*
|
|
62
|
-
* @param level string representation of Severity
|
|
63
|
-
* @returns Severity
|
|
64
|
-
*/
|
|
65
|
-
function fromString(level) {
|
|
66
|
-
switch (level) {
|
|
67
|
-
case 'debug':
|
|
68
|
-
return Severity.Debug;
|
|
69
|
-
case 'info':
|
|
70
|
-
return Severity.Info;
|
|
71
|
-
case 'warn':
|
|
72
|
-
case 'warning':
|
|
73
|
-
return Severity.Warning;
|
|
74
|
-
case 'error':
|
|
75
|
-
return Severity.Error;
|
|
76
|
-
case 'fatal':
|
|
77
|
-
return Severity.Fatal;
|
|
78
|
-
case 'critical':
|
|
79
|
-
return Severity.Critical;
|
|
80
|
-
case 'log':
|
|
81
|
-
default:
|
|
82
|
-
return Severity.Log;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
Severity.fromString = fromString;
|
|
86
|
-
})(exports.Severity || (exports.Severity = {}));
|
|
87
|
-
|
|
88
|
-
/** The status of an event. */
|
|
89
|
-
(function (Status) {
|
|
90
|
-
/** The status could not be determined. */
|
|
91
|
-
Status["Unknown"] = "unknown";
|
|
92
|
-
/** The event was skipped due to configuration or callbacks. */
|
|
93
|
-
Status["Skipped"] = "skipped";
|
|
94
|
-
/** The event was sent to Sentry successfully. */
|
|
95
|
-
Status["Success"] = "success";
|
|
96
|
-
/** The client is currently rate limited and will try again later. */
|
|
97
|
-
Status["RateLimit"] = "rate_limit";
|
|
98
|
-
/** The event could not be processed. */
|
|
99
|
-
Status["Invalid"] = "invalid";
|
|
100
|
-
/** A server-side error occurred during submission. */
|
|
101
|
-
Status["Failed"] = "failed";
|
|
102
|
-
})(exports.Status || (exports.Status = {}));
|
|
103
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace, import/export
|
|
104
|
-
(function (Status) {
|
|
105
|
-
/**
|
|
106
|
-
* Converts a HTTP status code into a {@link Status}.
|
|
107
|
-
*
|
|
108
|
-
* @param code The HTTP response status code.
|
|
109
|
-
* @returns The send status or {@link Status.Unknown}.
|
|
110
|
-
*/
|
|
111
|
-
function fromHttpCode(code) {
|
|
112
|
-
if (code >= 200 && code < 300) {
|
|
113
|
-
return Status.Success;
|
|
114
|
-
}
|
|
115
|
-
if (code === 429) {
|
|
116
|
-
return Status.RateLimit;
|
|
117
|
-
}
|
|
118
|
-
if (code >= 400 && code < 500) {
|
|
119
|
-
return Status.Invalid;
|
|
120
|
-
}
|
|
121
|
-
if (code >= 500) {
|
|
122
|
-
return Status.Failed;
|
|
123
|
-
}
|
|
124
|
-
return Status.Unknown;
|
|
125
|
-
}
|
|
126
|
-
Status.fromHttpCode = fromHttpCode;
|
|
127
|
-
})(exports.Status || (exports.Status = {}));
|
|
128
|
-
|
|
129
|
-
var TransactionSamplingMethod;
|
|
130
|
-
(function (TransactionSamplingMethod) {
|
|
131
|
-
TransactionSamplingMethod["Explicit"] = "explicitly_set";
|
|
132
|
-
TransactionSamplingMethod["Sampler"] = "client_sampler";
|
|
133
|
-
TransactionSamplingMethod["Rate"] = "client_rate";
|
|
134
|
-
TransactionSamplingMethod["Inheritance"] = "inheritance";
|
|
135
|
-
})(TransactionSamplingMethod || (TransactionSamplingMethod = {}));
|
|
136
|
-
|
|
137
|
-
var Outcome;
|
|
138
|
-
(function (Outcome) {
|
|
139
|
-
Outcome["BeforeSend"] = "before_send";
|
|
140
|
-
Outcome["EventProcessor"] = "event_processor";
|
|
141
|
-
Outcome["NetworkError"] = "network_error";
|
|
142
|
-
Outcome["QueueOverflow"] = "queue_overflow";
|
|
143
|
-
Outcome["RateLimitBackoff"] = "ratelimit_backoff";
|
|
144
|
-
Outcome["SampleRate"] = "sample_rate";
|
|
145
|
-
})(Outcome || (Outcome = {}));
|
|
22
|
+
const SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'];
|
|
146
23
|
|
|
147
24
|
/**
|
|
148
25
|
* Consumes the promise and logs the error when it rejects.
|
|
@@ -157,6 +34,33 @@ var Sentry = (function (exports) {
|
|
|
157
34
|
});
|
|
158
35
|
}
|
|
159
36
|
|
|
37
|
+
/**
|
|
38
|
+
* This module mostly exists for optimizations in the build process
|
|
39
|
+
* through rollup and terser. We define some global constants which
|
|
40
|
+
* are normally undefined. However terser overrides these with global
|
|
41
|
+
* definitions which can be evaluated by the static analyzer when
|
|
42
|
+
* creating a bundle.
|
|
43
|
+
*
|
|
44
|
+
* In turn the `isDebugBuild` and `isBrowserBundle` functions are pure
|
|
45
|
+
* and can help us remove unused code from the bundles.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* Figures out if we're building with debug functionality.
|
|
49
|
+
*
|
|
50
|
+
* @returns true if this is a debug build
|
|
51
|
+
*/
|
|
52
|
+
function isDebugBuild() {
|
|
53
|
+
return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !__SENTRY_BROWSER_BUNDLE__;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Figures out if we're building a browser bundle.
|
|
57
|
+
*
|
|
58
|
+
* @returns true if this is a browser bundle build.
|
|
59
|
+
*/
|
|
60
|
+
function isBrowserBundle() {
|
|
61
|
+
return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
|
|
62
|
+
}
|
|
63
|
+
|
|
160
64
|
/**
|
|
161
65
|
* NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
|
|
162
66
|
* you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
|
|
@@ -167,7 +71,10 @@ var Sentry = (function (exports) {
|
|
|
167
71
|
* @returns Answer to given question
|
|
168
72
|
*/
|
|
169
73
|
function isNodeEnv() {
|
|
170
|
-
|
|
74
|
+
// explicitly check for browser bundles as those can be optimized statically
|
|
75
|
+
// by terser/rollup.
|
|
76
|
+
return (!isBrowserBundle() &&
|
|
77
|
+
Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]');
|
|
171
78
|
}
|
|
172
79
|
/**
|
|
173
80
|
* Requires a module which is protected against bundler minification.
|
|
@@ -202,6 +109,8 @@ var Sentry = (function (exports) {
|
|
|
202
109
|
|
|
203
110
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
204
111
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
113
|
+
const objectToString = Object.prototype.toString;
|
|
205
114
|
/**
|
|
206
115
|
* Checks whether given value's type is one of a few Error or Error-like
|
|
207
116
|
* {@link isError}.
|
|
@@ -210,17 +119,18 @@ var Sentry = (function (exports) {
|
|
|
210
119
|
* @returns A boolean representing the result.
|
|
211
120
|
*/
|
|
212
121
|
function isError(wat) {
|
|
213
|
-
switch (
|
|
122
|
+
switch (objectToString.call(wat)) {
|
|
214
123
|
case '[object Error]':
|
|
215
|
-
return true;
|
|
216
124
|
case '[object Exception]':
|
|
217
|
-
return true;
|
|
218
125
|
case '[object DOMException]':
|
|
219
126
|
return true;
|
|
220
127
|
default:
|
|
221
128
|
return isInstanceOf(wat, Error);
|
|
222
129
|
}
|
|
223
130
|
}
|
|
131
|
+
function isBuiltin(wat, ty) {
|
|
132
|
+
return objectToString.call(wat) === `[object ${ty}]`;
|
|
133
|
+
}
|
|
224
134
|
/**
|
|
225
135
|
* Checks whether given value's type is ErrorEvent
|
|
226
136
|
* {@link isErrorEvent}.
|
|
@@ -229,7 +139,7 @@ var Sentry = (function (exports) {
|
|
|
229
139
|
* @returns A boolean representing the result.
|
|
230
140
|
*/
|
|
231
141
|
function isErrorEvent(wat) {
|
|
232
|
-
return
|
|
142
|
+
return isBuiltin(wat, 'ErrorEvent');
|
|
233
143
|
}
|
|
234
144
|
/**
|
|
235
145
|
* Checks whether given value's type is DOMError
|
|
@@ -239,7 +149,7 @@ var Sentry = (function (exports) {
|
|
|
239
149
|
* @returns A boolean representing the result.
|
|
240
150
|
*/
|
|
241
151
|
function isDOMError(wat) {
|
|
242
|
-
return
|
|
152
|
+
return isBuiltin(wat, 'DOMError');
|
|
243
153
|
}
|
|
244
154
|
/**
|
|
245
155
|
* Checks whether given value's type is DOMException
|
|
@@ -249,7 +159,7 @@ var Sentry = (function (exports) {
|
|
|
249
159
|
* @returns A boolean representing the result.
|
|
250
160
|
*/
|
|
251
161
|
function isDOMException(wat) {
|
|
252
|
-
return
|
|
162
|
+
return isBuiltin(wat, 'DOMException');
|
|
253
163
|
}
|
|
254
164
|
/**
|
|
255
165
|
* Checks whether given value's type is a string
|
|
@@ -259,10 +169,10 @@ var Sentry = (function (exports) {
|
|
|
259
169
|
* @returns A boolean representing the result.
|
|
260
170
|
*/
|
|
261
171
|
function isString(wat) {
|
|
262
|
-
return
|
|
172
|
+
return isBuiltin(wat, 'String');
|
|
263
173
|
}
|
|
264
174
|
/**
|
|
265
|
-
* Checks whether given value
|
|
175
|
+
* Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)
|
|
266
176
|
* {@link isPrimitive}.
|
|
267
177
|
*
|
|
268
178
|
* @param wat A value to be checked.
|
|
@@ -279,7 +189,7 @@ var Sentry = (function (exports) {
|
|
|
279
189
|
* @returns A boolean representing the result.
|
|
280
190
|
*/
|
|
281
191
|
function isPlainObject(wat) {
|
|
282
|
-
return
|
|
192
|
+
return isBuiltin(wat, 'Object');
|
|
283
193
|
}
|
|
284
194
|
/**
|
|
285
195
|
* Checks whether given value's type is an Event instance
|
|
@@ -309,7 +219,7 @@ var Sentry = (function (exports) {
|
|
|
309
219
|
* @returns A boolean representing the result.
|
|
310
220
|
*/
|
|
311
221
|
function isRegExp(wat) {
|
|
312
|
-
return
|
|
222
|
+
return isBuiltin(wat, 'RegExp');
|
|
313
223
|
}
|
|
314
224
|
/**
|
|
315
225
|
* Checks whether given value has a then function.
|
|
@@ -393,7 +303,6 @@ var Sentry = (function (exports) {
|
|
|
393
303
|
* @returns generated DOM path
|
|
394
304
|
*/
|
|
395
305
|
function _htmlElementAsString(el, keyAttrs) {
|
|
396
|
-
var _a, _b;
|
|
397
306
|
const elem = el;
|
|
398
307
|
const out = [];
|
|
399
308
|
let className;
|
|
@@ -406,9 +315,10 @@ var Sentry = (function (exports) {
|
|
|
406
315
|
}
|
|
407
316
|
out.push(elem.tagName.toLowerCase());
|
|
408
317
|
// Pairs of attribute keys defined in `serializeAttribute` and their values on element.
|
|
409
|
-
const keyAttrPairs =
|
|
318
|
+
const keyAttrPairs = keyAttrs && keyAttrs.length
|
|
319
|
+
? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
|
|
410
320
|
: null;
|
|
411
|
-
if (
|
|
321
|
+
if (keyAttrPairs && keyAttrPairs.length) {
|
|
412
322
|
keyAttrPairs.forEach(keyAttrPair => {
|
|
413
323
|
out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
|
|
414
324
|
});
|
|
@@ -485,88 +395,87 @@ var Sentry = (function (exports) {
|
|
|
485
395
|
|
|
486
396
|
/** Regular expression used to parse a Dsn. */
|
|
487
397
|
const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
398
|
+
function isValidProtocol(protocol) {
|
|
399
|
+
return protocol === 'http' || protocol === 'https';
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Renders the string representation of this Dsn.
|
|
403
|
+
*
|
|
404
|
+
* By default, this will render the public representation without the password
|
|
405
|
+
* component. To get the deprecated private representation, set `withPassword`
|
|
406
|
+
* to true.
|
|
407
|
+
*
|
|
408
|
+
* @param withPassword When set to true, the password will be included.
|
|
409
|
+
*/
|
|
410
|
+
function dsnToString(dsn, withPassword = false) {
|
|
411
|
+
const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
|
|
412
|
+
return (`${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
|
|
413
|
+
`@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`);
|
|
414
|
+
}
|
|
415
|
+
function dsnFromString(str) {
|
|
416
|
+
const match = DSN_REGEX.exec(str);
|
|
417
|
+
if (!match) {
|
|
418
|
+
throw new SentryError(`Invalid Sentry Dsn: ${str}`);
|
|
501
419
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
`@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`);
|
|
515
|
-
}
|
|
516
|
-
/** Parses a string into this Dsn. */
|
|
517
|
-
_fromString(str) {
|
|
518
|
-
const match = DSN_REGEX.exec(str);
|
|
519
|
-
if (!match) {
|
|
520
|
-
throw new SentryError(ERROR_MESSAGE);
|
|
521
|
-
}
|
|
522
|
-
const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
|
|
523
|
-
let path = '';
|
|
524
|
-
let projectId = lastPath;
|
|
525
|
-
const split = projectId.split('/');
|
|
526
|
-
if (split.length > 1) {
|
|
527
|
-
path = split.slice(0, -1).join('/');
|
|
528
|
-
projectId = split.pop();
|
|
529
|
-
}
|
|
530
|
-
if (projectId) {
|
|
531
|
-
const projectMatch = projectId.match(/^\d+/);
|
|
532
|
-
if (projectMatch) {
|
|
533
|
-
projectId = projectMatch[0];
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
this._fromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
|
|
537
|
-
}
|
|
538
|
-
/** Maps Dsn components into this instance. */
|
|
539
|
-
_fromComponents(components) {
|
|
540
|
-
// TODO this is for backwards compatibility, and can be removed in a future version
|
|
541
|
-
if ('user' in components && !('publicKey' in components)) {
|
|
542
|
-
components.publicKey = components.user;
|
|
543
|
-
}
|
|
544
|
-
this.user = components.publicKey || '';
|
|
545
|
-
this.protocol = components.protocol;
|
|
546
|
-
this.publicKey = components.publicKey || '';
|
|
547
|
-
this.pass = components.pass || '';
|
|
548
|
-
this.host = components.host;
|
|
549
|
-
this.port = components.port || '';
|
|
550
|
-
this.path = components.path || '';
|
|
551
|
-
this.projectId = components.projectId;
|
|
552
|
-
}
|
|
553
|
-
/** Validates this Dsn and throws on error. */
|
|
554
|
-
_validate() {
|
|
555
|
-
['protocol', 'publicKey', 'host', 'projectId'].forEach(component => {
|
|
556
|
-
if (!this[component]) {
|
|
557
|
-
throw new SentryError(`${ERROR_MESSAGE}: ${component} missing`);
|
|
558
|
-
}
|
|
559
|
-
});
|
|
560
|
-
if (!this.projectId.match(/^\d+$/)) {
|
|
561
|
-
throw new SentryError(`${ERROR_MESSAGE}: Invalid projectId ${this.projectId}`);
|
|
562
|
-
}
|
|
563
|
-
if (this.protocol !== 'http' && this.protocol !== 'https') {
|
|
564
|
-
throw new SentryError(`${ERROR_MESSAGE}: Invalid protocol ${this.protocol}`);
|
|
420
|
+
const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
|
|
421
|
+
let path = '';
|
|
422
|
+
let projectId = lastPath;
|
|
423
|
+
const split = projectId.split('/');
|
|
424
|
+
if (split.length > 1) {
|
|
425
|
+
path = split.slice(0, -1).join('/');
|
|
426
|
+
projectId = split.pop();
|
|
427
|
+
}
|
|
428
|
+
if (projectId) {
|
|
429
|
+
const projectMatch = projectId.match(/^\d+/);
|
|
430
|
+
if (projectMatch) {
|
|
431
|
+
projectId = projectMatch[0];
|
|
565
432
|
}
|
|
566
|
-
|
|
567
|
-
|
|
433
|
+
}
|
|
434
|
+
return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
|
|
435
|
+
}
|
|
436
|
+
function dsnFromComponents(components) {
|
|
437
|
+
// TODO this is for backwards compatibility, and can be removed in a future version
|
|
438
|
+
if ('user' in components && !('publicKey' in components)) {
|
|
439
|
+
components.publicKey = components.user;
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
user: components.publicKey || '',
|
|
443
|
+
protocol: components.protocol,
|
|
444
|
+
publicKey: components.publicKey || '',
|
|
445
|
+
pass: components.pass || '',
|
|
446
|
+
host: components.host,
|
|
447
|
+
port: components.port || '',
|
|
448
|
+
path: components.path || '',
|
|
449
|
+
projectId: components.projectId,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function validateDsn(dsn) {
|
|
453
|
+
if (!isDebugBuild()) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const { port, projectId, protocol } = dsn;
|
|
457
|
+
const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];
|
|
458
|
+
requiredComponents.forEach(component => {
|
|
459
|
+
if (!dsn[component]) {
|
|
460
|
+
throw new SentryError(`Invalid Sentry Dsn: ${component} missing`);
|
|
568
461
|
}
|
|
462
|
+
});
|
|
463
|
+
if (!projectId.match(/^\d+$/)) {
|
|
464
|
+
throw new SentryError(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);
|
|
465
|
+
}
|
|
466
|
+
if (!isValidProtocol(protocol)) {
|
|
467
|
+
throw new SentryError(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);
|
|
468
|
+
}
|
|
469
|
+
if (port && isNaN(parseInt(port, 10))) {
|
|
470
|
+
throw new SentryError(`Invalid Sentry Dsn: Invalid port ${port}`);
|
|
569
471
|
}
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
/** The Sentry Dsn, identifying a Sentry instance and project. */
|
|
475
|
+
function makeDsn(from) {
|
|
476
|
+
const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
|
|
477
|
+
validateDsn(components);
|
|
478
|
+
return components;
|
|
570
479
|
}
|
|
571
480
|
|
|
572
481
|
// TODO: Implement different loggers for different environments
|
|
@@ -653,54 +562,44 @@ var Sentry = (function (exports) {
|
|
|
653
562
|
|
|
654
563
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
655
564
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
656
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
657
565
|
/**
|
|
658
|
-
*
|
|
566
|
+
* Helper to decycle json objects
|
|
659
567
|
*/
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
* Sets obj to remember.
|
|
667
|
-
* @param obj Object to remember
|
|
668
|
-
*/
|
|
669
|
-
memoize(obj) {
|
|
670
|
-
if (this._hasWeakSet) {
|
|
671
|
-
if (this._inner.has(obj)) {
|
|
568
|
+
function memoBuilder() {
|
|
569
|
+
const hasWeakSet = typeof WeakSet === 'function';
|
|
570
|
+
const inner = hasWeakSet ? new WeakSet() : [];
|
|
571
|
+
function memoize(obj) {
|
|
572
|
+
if (hasWeakSet) {
|
|
573
|
+
if (inner.has(obj)) {
|
|
672
574
|
return true;
|
|
673
575
|
}
|
|
674
|
-
|
|
576
|
+
inner.add(obj);
|
|
675
577
|
return false;
|
|
676
578
|
}
|
|
677
579
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
678
|
-
for (let i = 0; i <
|
|
679
|
-
const value =
|
|
580
|
+
for (let i = 0; i < inner.length; i++) {
|
|
581
|
+
const value = inner[i];
|
|
680
582
|
if (value === obj) {
|
|
681
583
|
return true;
|
|
682
584
|
}
|
|
683
585
|
}
|
|
684
|
-
|
|
586
|
+
inner.push(obj);
|
|
685
587
|
return false;
|
|
686
588
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
*/
|
|
691
|
-
unmemoize(obj) {
|
|
692
|
-
if (this._hasWeakSet) {
|
|
693
|
-
this._inner.delete(obj);
|
|
589
|
+
function unmemoize(obj) {
|
|
590
|
+
if (hasWeakSet) {
|
|
591
|
+
inner.delete(obj);
|
|
694
592
|
}
|
|
695
593
|
else {
|
|
696
|
-
for (let i = 0; i <
|
|
697
|
-
if (
|
|
698
|
-
|
|
594
|
+
for (let i = 0; i < inner.length; i++) {
|
|
595
|
+
if (inner[i] === obj) {
|
|
596
|
+
inner.splice(i, 1);
|
|
699
597
|
break;
|
|
700
598
|
}
|
|
701
599
|
}
|
|
702
600
|
}
|
|
703
601
|
}
|
|
602
|
+
return [memoize, unmemoize];
|
|
704
603
|
}
|
|
705
604
|
|
|
706
605
|
const defaultFunctionName = '<anonymous>';
|
|
@@ -797,13 +696,7 @@ var Sentry = (function (exports) {
|
|
|
797
696
|
// otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
|
|
798
697
|
if (typeof wrapped === 'function') {
|
|
799
698
|
try {
|
|
800
|
-
wrapped
|
|
801
|
-
Object.defineProperties(wrapped, {
|
|
802
|
-
__sentry_original__: {
|
|
803
|
-
enumerable: false,
|
|
804
|
-
value: original,
|
|
805
|
-
},
|
|
806
|
-
});
|
|
699
|
+
markFunctionWrapped(wrapped, original);
|
|
807
700
|
}
|
|
808
701
|
catch (_Oo) {
|
|
809
702
|
// This can throw if multiple fill happens on a global object like XMLHttpRequest
|
|
@@ -812,6 +705,41 @@ var Sentry = (function (exports) {
|
|
|
812
705
|
}
|
|
813
706
|
source[name] = wrapped;
|
|
814
707
|
}
|
|
708
|
+
/**
|
|
709
|
+
* Defines a non enumerable property. This creates a non enumerable property on an object.
|
|
710
|
+
*
|
|
711
|
+
* @param func The function to set a property to
|
|
712
|
+
* @param name the name of the special sentry property
|
|
713
|
+
* @param value the property to define
|
|
714
|
+
*/
|
|
715
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
716
|
+
function addNonEnumerableProperty(func, name, value) {
|
|
717
|
+
Object.defineProperty(func, name, {
|
|
718
|
+
value: value,
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Remembers the original function on the wrapped function and
|
|
723
|
+
* patches up the prototype.
|
|
724
|
+
*
|
|
725
|
+
* @param wrapped the wrapper function
|
|
726
|
+
* @param original the original function that gets wrapped
|
|
727
|
+
*/
|
|
728
|
+
function markFunctionWrapped(wrapped, original) {
|
|
729
|
+
const proto = original.prototype || {};
|
|
730
|
+
wrapped.prototype = original.prototype = proto;
|
|
731
|
+
addNonEnumerableProperty(wrapped, '__sentry_original__', original);
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* This extracts the original function if available. See
|
|
735
|
+
* `markFunctionWrapped` for more information.
|
|
736
|
+
*
|
|
737
|
+
* @param func the function to unwrap
|
|
738
|
+
* @returns the unwrapped version of the function if available.
|
|
739
|
+
*/
|
|
740
|
+
function getOriginalFunction(func) {
|
|
741
|
+
return func.__sentry_original__;
|
|
742
|
+
}
|
|
815
743
|
/**
|
|
816
744
|
* Encodes given object into url-friendly format
|
|
817
745
|
*
|
|
@@ -910,11 +838,11 @@ var Sentry = (function (exports) {
|
|
|
910
838
|
* unchanged.
|
|
911
839
|
*/
|
|
912
840
|
function serializeValue(value) {
|
|
913
|
-
const type = Object.prototype.toString.call(value);
|
|
914
841
|
// Node.js REPL notation
|
|
915
842
|
if (typeof value === 'string') {
|
|
916
843
|
return value;
|
|
917
844
|
}
|
|
845
|
+
const type = Object.prototype.toString.call(value);
|
|
918
846
|
if (type === '[object Object]') {
|
|
919
847
|
return '[Object]';
|
|
920
848
|
}
|
|
@@ -984,8 +912,8 @@ var Sentry = (function (exports) {
|
|
|
984
912
|
* @param memo Optional Memo class handling decycling
|
|
985
913
|
*/
|
|
986
914
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
987
|
-
function walk(key, value, depth = +Infinity, memo =
|
|
988
|
-
// If we reach the maximum depth, serialize whatever
|
|
915
|
+
function walk(key, value, depth = +Infinity, memo = memoBuilder()) {
|
|
916
|
+
// If we reach the maximum depth, serialize whatever is left
|
|
989
917
|
if (depth === 0) {
|
|
990
918
|
return serializeValue(value);
|
|
991
919
|
}
|
|
@@ -995,17 +923,18 @@ var Sentry = (function (exports) {
|
|
|
995
923
|
return value.toJSON();
|
|
996
924
|
}
|
|
997
925
|
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
998
|
-
// If normalized value is a primitive, there are no branches left to walk, so
|
|
926
|
+
// If normalized value is a primitive, there are no branches left to walk, so bail out
|
|
999
927
|
const normalized = normalizeValue(value, key);
|
|
1000
928
|
if (isPrimitive(normalized)) {
|
|
1001
929
|
return normalized;
|
|
1002
930
|
}
|
|
1003
|
-
// Create source that we will use for next
|
|
931
|
+
// Create source that we will use for the next iteration. It will either be an objectified error object (`Error` type
|
|
932
|
+
// with extracted key:value pairs) or the input itself.
|
|
1004
933
|
const source = getWalkSource(value);
|
|
1005
934
|
// Create an accumulator that will act as a parent for all future itterations of that branch
|
|
1006
935
|
const acc = Array.isArray(value) ? [] : {};
|
|
1007
936
|
// If we already walked that branch, bail out, as it's circular reference
|
|
1008
|
-
if (memo
|
|
937
|
+
if (memo[0](value)) {
|
|
1009
938
|
return '[Circular ~]';
|
|
1010
939
|
}
|
|
1011
940
|
// Walk all keys of the source
|
|
@@ -1018,7 +947,7 @@ var Sentry = (function (exports) {
|
|
|
1018
947
|
acc[innerKey] = walk(innerKey, source[innerKey], depth - 1, memo);
|
|
1019
948
|
}
|
|
1020
949
|
// Once walked through all the branches, remove the parent from memo storage
|
|
1021
|
-
memo
|
|
950
|
+
memo[1](value);
|
|
1022
951
|
// Return accumulated values
|
|
1023
952
|
return acc;
|
|
1024
953
|
}
|
|
@@ -1151,7 +1080,9 @@ var Sentry = (function (exports) {
|
|
|
1151
1080
|
doc.head.removeChild(sandbox);
|
|
1152
1081
|
}
|
|
1153
1082
|
catch (err) {
|
|
1154
|
-
|
|
1083
|
+
if (isDebugBuild()) {
|
|
1084
|
+
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
|
|
1085
|
+
}
|
|
1155
1086
|
}
|
|
1156
1087
|
}
|
|
1157
1088
|
return result;
|
|
@@ -1163,9 +1094,9 @@ var Sentry = (function (exports) {
|
|
|
1163
1094
|
* @returns Answer to the given question.
|
|
1164
1095
|
*/
|
|
1165
1096
|
function supportsReferrerPolicy() {
|
|
1166
|
-
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
|
1167
|
-
// https://caniuse.com/#feat=referrer-policy
|
|
1168
|
-
//
|
|
1097
|
+
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
|
|
1098
|
+
// (see https://caniuse.com/#feat=referrer-policy),
|
|
1099
|
+
// it doesn't. And it throws an exception instead of ignoring this parameter...
|
|
1169
1100
|
// REF: https://github.com/getsentry/raven-js/issues/1233
|
|
1170
1101
|
if (!supportsFetch()) {
|
|
1171
1102
|
return false;
|
|
@@ -1250,13 +1181,10 @@ var Sentry = (function (exports) {
|
|
|
1250
1181
|
* Use at your own risk, this might break without changelog notice, only used internally.
|
|
1251
1182
|
* @hidden
|
|
1252
1183
|
*/
|
|
1253
|
-
function addInstrumentationHandler(
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
handlers[handler.type] = handlers[handler.type] || [];
|
|
1258
|
-
handlers[handler.type].push(handler.callback);
|
|
1259
|
-
instrument(handler.type);
|
|
1184
|
+
function addInstrumentationHandler(type, callback) {
|
|
1185
|
+
handlers[type] = handlers[type] || [];
|
|
1186
|
+
handlers[type].push(callback);
|
|
1187
|
+
instrument(type);
|
|
1260
1188
|
}
|
|
1261
1189
|
/** JSDoc */
|
|
1262
1190
|
function triggerHandlers(type, data) {
|
|
@@ -1268,7 +1196,9 @@ var Sentry = (function (exports) {
|
|
|
1268
1196
|
handler(data);
|
|
1269
1197
|
}
|
|
1270
1198
|
catch (e) {
|
|
1271
|
-
|
|
1199
|
+
if (isDebugBuild()) {
|
|
1200
|
+
logger.error(`Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError: ${e}`);
|
|
1201
|
+
}
|
|
1272
1202
|
}
|
|
1273
1203
|
}
|
|
1274
1204
|
}
|
|
@@ -1349,23 +1279,20 @@ var Sentry = (function (exports) {
|
|
|
1349
1279
|
if (!('XMLHttpRequest' in global$2)) {
|
|
1350
1280
|
return;
|
|
1351
1281
|
}
|
|
1352
|
-
// Poor man's implementation of ES6 `Map`, tracking and keeping in sync key and value separately.
|
|
1353
|
-
const requestKeys = [];
|
|
1354
|
-
const requestValues = [];
|
|
1355
1282
|
const xhrproto = XMLHttpRequest.prototype;
|
|
1356
1283
|
fill(xhrproto, 'open', function (originalOpen) {
|
|
1357
1284
|
return function (...args) {
|
|
1358
1285
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1359
1286
|
const xhr = this;
|
|
1360
1287
|
const url = args[1];
|
|
1361
|
-
xhr.__sentry_xhr__ = {
|
|
1288
|
+
const xhrInfo = (xhr.__sentry_xhr__ = {
|
|
1362
1289
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1363
1290
|
method: isString(args[0]) ? args[0].toUpperCase() : args[0],
|
|
1364
1291
|
url: args[1],
|
|
1365
|
-
};
|
|
1292
|
+
});
|
|
1366
1293
|
// if Sentry key appears in URL, don't capture it as a request
|
|
1367
1294
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1368
|
-
if (isString(url) &&
|
|
1295
|
+
if (isString(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) {
|
|
1369
1296
|
xhr.__sentry_own_request__ = true;
|
|
1370
1297
|
}
|
|
1371
1298
|
const onreadystatechangeHandler = function () {
|
|
@@ -1373,23 +1300,7 @@ var Sentry = (function (exports) {
|
|
|
1373
1300
|
try {
|
|
1374
1301
|
// touching statusCode in some platforms throws
|
|
1375
1302
|
// an exception
|
|
1376
|
-
|
|
1377
|
-
xhr.__sentry_xhr__.status_code = xhr.status;
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
catch (e) {
|
|
1381
|
-
/* do nothing */
|
|
1382
|
-
}
|
|
1383
|
-
try {
|
|
1384
|
-
const requestPos = requestKeys.indexOf(xhr);
|
|
1385
|
-
if (requestPos !== -1) {
|
|
1386
|
-
// Make sure to pop both key and value to keep it in sync.
|
|
1387
|
-
requestKeys.splice(requestPos);
|
|
1388
|
-
const args = requestValues.splice(requestPos)[0];
|
|
1389
|
-
if (xhr.__sentry_xhr__ && args[0] !== undefined) {
|
|
1390
|
-
xhr.__sentry_xhr__.body = args[0];
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1303
|
+
xhrInfo.status_code = xhr.status;
|
|
1393
1304
|
}
|
|
1394
1305
|
catch (e) {
|
|
1395
1306
|
/* do nothing */
|
|
@@ -1418,8 +1329,9 @@ var Sentry = (function (exports) {
|
|
|
1418
1329
|
});
|
|
1419
1330
|
fill(xhrproto, 'send', function (originalSend) {
|
|
1420
1331
|
return function (...args) {
|
|
1421
|
-
|
|
1422
|
-
|
|
1332
|
+
if (this.__sentry_xhr__ && args[0] !== undefined) {
|
|
1333
|
+
this.__sentry_xhr__.body = args[0];
|
|
1334
|
+
}
|
|
1423
1335
|
triggerHandlers('xhr', {
|
|
1424
1336
|
args,
|
|
1425
1337
|
startTimestamp: Date.now(),
|
|
@@ -1754,22 +1666,26 @@ var Sentry = (function (exports) {
|
|
|
1754
1666
|
relative: match[5] + query + fragment,
|
|
1755
1667
|
};
|
|
1756
1668
|
}
|
|
1669
|
+
function getFirstException(event) {
|
|
1670
|
+
return event.exception && event.exception.values ? event.exception.values[0] : undefined;
|
|
1671
|
+
}
|
|
1757
1672
|
/**
|
|
1758
1673
|
* Extracts either message or type+value from an event that can be used for user-facing logs
|
|
1759
1674
|
* @returns event's description
|
|
1760
1675
|
*/
|
|
1761
1676
|
function getEventDescription(event) {
|
|
1762
|
-
|
|
1763
|
-
|
|
1677
|
+
const { message, event_id: eventId } = event;
|
|
1678
|
+
if (message) {
|
|
1679
|
+
return message;
|
|
1764
1680
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
if (
|
|
1768
|
-
return `${
|
|
1681
|
+
const firstException = getFirstException(event);
|
|
1682
|
+
if (firstException) {
|
|
1683
|
+
if (firstException.type && firstException.value) {
|
|
1684
|
+
return `${firstException.type}: ${firstException.value}`;
|
|
1769
1685
|
}
|
|
1770
|
-
return
|
|
1686
|
+
return firstException.type || firstException.value || eventId || '<unknown>';
|
|
1771
1687
|
}
|
|
1772
|
-
return
|
|
1688
|
+
return eventId || '<unknown>';
|
|
1773
1689
|
}
|
|
1774
1690
|
/**
|
|
1775
1691
|
* Adds exception values, type and value to an synthetic Exception.
|
|
@@ -1779,11 +1695,15 @@ var Sentry = (function (exports) {
|
|
|
1779
1695
|
* @hidden
|
|
1780
1696
|
*/
|
|
1781
1697
|
function addExceptionTypeValue(event, value, type) {
|
|
1782
|
-
event.exception = event.exception || {};
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1698
|
+
const exception = (event.exception = event.exception || {});
|
|
1699
|
+
const values = (exception.values = exception.values || []);
|
|
1700
|
+
const firstException = (values[0] = values[0] || {});
|
|
1701
|
+
if (!firstException.value) {
|
|
1702
|
+
firstException.value = value || '';
|
|
1703
|
+
}
|
|
1704
|
+
if (!firstException.type) {
|
|
1705
|
+
firstException.type = type || 'Error';
|
|
1706
|
+
}
|
|
1787
1707
|
}
|
|
1788
1708
|
/**
|
|
1789
1709
|
* Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
|
|
@@ -1793,17 +1713,16 @@ var Sentry = (function (exports) {
|
|
|
1793
1713
|
* @hidden
|
|
1794
1714
|
*/
|
|
1795
1715
|
function addExceptionMechanism(event, newMechanism) {
|
|
1796
|
-
|
|
1797
|
-
if (!
|
|
1716
|
+
const firstException = getFirstException(event);
|
|
1717
|
+
if (!firstException) {
|
|
1798
1718
|
return;
|
|
1799
1719
|
}
|
|
1800
|
-
const exceptionValue0 = event.exception.values[0];
|
|
1801
1720
|
const defaultMechanism = { type: 'generic', handled: true };
|
|
1802
|
-
const currentMechanism =
|
|
1803
|
-
|
|
1721
|
+
const currentMechanism = firstException.mechanism;
|
|
1722
|
+
firstException.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
|
|
1804
1723
|
if (newMechanism && 'data' in newMechanism) {
|
|
1805
|
-
const mergedData = Object.assign(Object.assign({}, (
|
|
1806
|
-
|
|
1724
|
+
const mergedData = Object.assign(Object.assign({}, (currentMechanism && currentMechanism.data)), newMechanism.data);
|
|
1725
|
+
firstException.mechanism.data = mergedData;
|
|
1807
1726
|
}
|
|
1808
1727
|
}
|
|
1809
1728
|
const defaultRetryAfter = 60 * 1000; // 60 seconds
|
|
@@ -1848,17 +1767,14 @@ var Sentry = (function (exports) {
|
|
|
1848
1767
|
* @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
|
|
1849
1768
|
*/
|
|
1850
1769
|
function checkOrSetAlreadyCaught(exception) {
|
|
1851
|
-
var _a;
|
|
1852
1770
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1853
|
-
if (
|
|
1771
|
+
if (exception && exception.__sentry_captured__) {
|
|
1854
1772
|
return true;
|
|
1855
1773
|
}
|
|
1856
1774
|
try {
|
|
1857
1775
|
// set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
|
|
1858
1776
|
// `ExtraErrorData` integration
|
|
1859
|
-
|
|
1860
|
-
value: true,
|
|
1861
|
-
});
|
|
1777
|
+
addNonEnumerableProperty(exception, '__sentry_captured__', true);
|
|
1862
1778
|
}
|
|
1863
1779
|
catch (err) {
|
|
1864
1780
|
// `exception` is a primitive, so we can't mark it seen
|
|
@@ -1867,25 +1783,47 @@ var Sentry = (function (exports) {
|
|
|
1867
1783
|
}
|
|
1868
1784
|
|
|
1869
1785
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1786
|
+
/**
|
|
1787
|
+
* Creates a resolved sync promise.
|
|
1788
|
+
*
|
|
1789
|
+
* @param value the value to resolve the promise with
|
|
1790
|
+
* @returns the resolved sync promise
|
|
1791
|
+
*/
|
|
1792
|
+
function resolvedSyncPromise(value) {
|
|
1793
|
+
return new SyncPromise(resolve => {
|
|
1794
|
+
resolve(value);
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* Creates a rejected sync promise.
|
|
1799
|
+
*
|
|
1800
|
+
* @param value the value to reject the promise with
|
|
1801
|
+
* @returns the rejected sync promise
|
|
1802
|
+
*/
|
|
1803
|
+
function rejectedSyncPromise(reason) {
|
|
1804
|
+
return new SyncPromise((_, reject) => {
|
|
1805
|
+
reject(reason);
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1870
1808
|
/**
|
|
1871
1809
|
* Thenable class that behaves like a Promise and follows it's interface
|
|
1872
1810
|
* but is not async internally
|
|
1873
1811
|
*/
|
|
1874
1812
|
class SyncPromise {
|
|
1875
1813
|
constructor(executor) {
|
|
1876
|
-
this._state =
|
|
1814
|
+
this._state = 0 /* PENDING */;
|
|
1877
1815
|
this._handlers = [];
|
|
1878
1816
|
/** JSDoc */
|
|
1879
1817
|
this._resolve = (value) => {
|
|
1880
|
-
this._setResult(
|
|
1818
|
+
this._setResult(1 /* RESOLVED */, value);
|
|
1881
1819
|
};
|
|
1882
1820
|
/** JSDoc */
|
|
1883
1821
|
this._reject = (reason) => {
|
|
1884
|
-
this._setResult(
|
|
1822
|
+
this._setResult(2 /* REJECTED */, reason);
|
|
1885
1823
|
};
|
|
1886
1824
|
/** JSDoc */
|
|
1887
1825
|
this._setResult = (state, value) => {
|
|
1888
|
-
if (this._state !==
|
|
1826
|
+
if (this._state !== 0 /* PENDING */) {
|
|
1889
1827
|
return;
|
|
1890
1828
|
}
|
|
1891
1829
|
if (isThenable(value)) {
|
|
@@ -1896,35 +1834,25 @@ var Sentry = (function (exports) {
|
|
|
1896
1834
|
this._value = value;
|
|
1897
1835
|
this._executeHandlers();
|
|
1898
1836
|
};
|
|
1899
|
-
// TODO: FIXME
|
|
1900
|
-
/** JSDoc */
|
|
1901
|
-
this._attachHandler = (handler) => {
|
|
1902
|
-
this._handlers = this._handlers.concat(handler);
|
|
1903
|
-
this._executeHandlers();
|
|
1904
|
-
};
|
|
1905
1837
|
/** JSDoc */
|
|
1906
1838
|
this._executeHandlers = () => {
|
|
1907
|
-
if (this._state ===
|
|
1839
|
+
if (this._state === 0 /* PENDING */) {
|
|
1908
1840
|
return;
|
|
1909
1841
|
}
|
|
1910
1842
|
const cachedHandlers = this._handlers.slice();
|
|
1911
1843
|
this._handlers = [];
|
|
1912
1844
|
cachedHandlers.forEach(handler => {
|
|
1913
|
-
if (handler
|
|
1845
|
+
if (handler[0]) {
|
|
1914
1846
|
return;
|
|
1915
1847
|
}
|
|
1916
|
-
if (this._state ===
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
handler.onfulfilled(this._value);
|
|
1920
|
-
}
|
|
1848
|
+
if (this._state === 1 /* RESOLVED */) {
|
|
1849
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1850
|
+
handler[1](this._value);
|
|
1921
1851
|
}
|
|
1922
|
-
if (this._state ===
|
|
1923
|
-
|
|
1924
|
-
handler.onrejected(this._value);
|
|
1925
|
-
}
|
|
1852
|
+
if (this._state === 2 /* REJECTED */) {
|
|
1853
|
+
handler[2](this._value);
|
|
1926
1854
|
}
|
|
1927
|
-
handler
|
|
1855
|
+
handler[0] = true;
|
|
1928
1856
|
});
|
|
1929
1857
|
};
|
|
1930
1858
|
try {
|
|
@@ -1935,80 +1863,40 @@ var Sentry = (function (exports) {
|
|
|
1935
1863
|
}
|
|
1936
1864
|
}
|
|
1937
1865
|
/** JSDoc */
|
|
1938
|
-
static resolve(value) {
|
|
1939
|
-
return new SyncPromise(resolve => {
|
|
1940
|
-
resolve(value);
|
|
1941
|
-
});
|
|
1942
|
-
}
|
|
1943
|
-
/** JSDoc */
|
|
1944
|
-
static reject(reason) {
|
|
1945
|
-
return new SyncPromise((_, reject) => {
|
|
1946
|
-
reject(reason);
|
|
1947
|
-
});
|
|
1948
|
-
}
|
|
1949
|
-
/** JSDoc */
|
|
1950
|
-
static all(collection) {
|
|
1951
|
-
return new SyncPromise((resolve, reject) => {
|
|
1952
|
-
if (!Array.isArray(collection)) {
|
|
1953
|
-
reject(new TypeError(`Promise.all requires an array as input.`));
|
|
1954
|
-
return;
|
|
1955
|
-
}
|
|
1956
|
-
if (collection.length === 0) {
|
|
1957
|
-
resolve([]);
|
|
1958
|
-
return;
|
|
1959
|
-
}
|
|
1960
|
-
let counter = collection.length;
|
|
1961
|
-
const resolvedCollection = [];
|
|
1962
|
-
collection.forEach((item, index) => {
|
|
1963
|
-
void SyncPromise.resolve(item)
|
|
1964
|
-
.then(value => {
|
|
1965
|
-
resolvedCollection[index] = value;
|
|
1966
|
-
counter -= 1;
|
|
1967
|
-
if (counter !== 0) {
|
|
1968
|
-
return;
|
|
1969
|
-
}
|
|
1970
|
-
resolve(resolvedCollection);
|
|
1971
|
-
})
|
|
1972
|
-
.then(null, reject);
|
|
1973
|
-
});
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
/** JSDoc */
|
|
1977
1866
|
then(onfulfilled, onrejected) {
|
|
1978
1867
|
return new SyncPromise((resolve, reject) => {
|
|
1979
|
-
this.
|
|
1980
|
-
|
|
1981
|
-
|
|
1868
|
+
this._handlers.push([
|
|
1869
|
+
false,
|
|
1870
|
+
result => {
|
|
1982
1871
|
if (!onfulfilled) {
|
|
1983
1872
|
// TODO: ¯\_(ツ)_/¯
|
|
1984
1873
|
// TODO: FIXME
|
|
1985
1874
|
resolve(result);
|
|
1986
|
-
return;
|
|
1987
|
-
}
|
|
1988
|
-
try {
|
|
1989
|
-
resolve(onfulfilled(result));
|
|
1990
|
-
return;
|
|
1991
1875
|
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1876
|
+
else {
|
|
1877
|
+
try {
|
|
1878
|
+
resolve(onfulfilled(result));
|
|
1879
|
+
}
|
|
1880
|
+
catch (e) {
|
|
1881
|
+
reject(e);
|
|
1882
|
+
}
|
|
1995
1883
|
}
|
|
1996
1884
|
},
|
|
1997
|
-
|
|
1885
|
+
reason => {
|
|
1998
1886
|
if (!onrejected) {
|
|
1999
1887
|
reject(reason);
|
|
2000
|
-
return;
|
|
2001
1888
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
1889
|
+
else {
|
|
1890
|
+
try {
|
|
1891
|
+
resolve(onrejected(reason));
|
|
1892
|
+
}
|
|
1893
|
+
catch (e) {
|
|
1894
|
+
reject(e);
|
|
1895
|
+
}
|
|
2009
1896
|
}
|
|
2010
1897
|
},
|
|
2011
|
-
|
|
1898
|
+
]);
|
|
1899
|
+
this._executeHandlers();
|
|
2012
1900
|
});
|
|
2013
1901
|
}
|
|
2014
1902
|
/** JSDoc */
|
|
@@ -2041,24 +1929,25 @@ var Sentry = (function (exports) {
|
|
|
2041
1929
|
});
|
|
2042
1930
|
});
|
|
2043
1931
|
}
|
|
2044
|
-
/** JSDoc */
|
|
2045
|
-
toString() {
|
|
2046
|
-
return '[object SyncPromise]';
|
|
2047
|
-
}
|
|
2048
1932
|
}
|
|
2049
1933
|
|
|
2050
|
-
/**
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
1934
|
+
/**
|
|
1935
|
+
* Creates an new PromiseBuffer object with the specified limit
|
|
1936
|
+
* @param limit max number of promises that can be stored in the buffer
|
|
1937
|
+
*/
|
|
1938
|
+
function makePromiseBuffer(limit) {
|
|
1939
|
+
const buffer = [];
|
|
1940
|
+
function isReady() {
|
|
1941
|
+
return limit === undefined || buffer.length < limit;
|
|
2056
1942
|
}
|
|
2057
1943
|
/**
|
|
2058
|
-
*
|
|
1944
|
+
* Remove a promise from the queue.
|
|
1945
|
+
*
|
|
1946
|
+
* @param task Can be any PromiseLike<T>
|
|
1947
|
+
* @returns Removed promise.
|
|
2059
1948
|
*/
|
|
2060
|
-
|
|
2061
|
-
return
|
|
1949
|
+
function remove(task) {
|
|
1950
|
+
return buffer.splice(buffer.indexOf(task), 1)[0];
|
|
2062
1951
|
}
|
|
2063
1952
|
/**
|
|
2064
1953
|
* Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
|
|
@@ -2070,41 +1959,25 @@ var Sentry = (function (exports) {
|
|
|
2070
1959
|
* limit check.
|
|
2071
1960
|
* @returns The original promise.
|
|
2072
1961
|
*/
|
|
2073
|
-
add(taskProducer) {
|
|
2074
|
-
if (!
|
|
2075
|
-
return
|
|
1962
|
+
function add(taskProducer) {
|
|
1963
|
+
if (!isReady()) {
|
|
1964
|
+
return rejectedSyncPromise(new SentryError('Not adding Promise due to buffer limit reached.'));
|
|
2076
1965
|
}
|
|
2077
1966
|
// start the task and add its promise to the queue
|
|
2078
1967
|
const task = taskProducer();
|
|
2079
|
-
if (
|
|
2080
|
-
|
|
1968
|
+
if (buffer.indexOf(task) === -1) {
|
|
1969
|
+
buffer.push(task);
|
|
2081
1970
|
}
|
|
2082
1971
|
void task
|
|
2083
|
-
.then(() =>
|
|
1972
|
+
.then(() => remove(task))
|
|
2084
1973
|
// Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
|
|
2085
1974
|
// rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
|
|
2086
1975
|
// have promises, so TS has to polyfill when down-compiling.)
|
|
2087
|
-
.then(null, () =>
|
|
2088
|
-
// We have to add another catch here because `
|
|
1976
|
+
.then(null, () => remove(task).then(null, () => {
|
|
1977
|
+
// We have to add another catch here because `remove()` starts a new promise chain.
|
|
2089
1978
|
}));
|
|
2090
1979
|
return task;
|
|
2091
1980
|
}
|
|
2092
|
-
/**
|
|
2093
|
-
* Remove a promise from the queue.
|
|
2094
|
-
*
|
|
2095
|
-
* @param task Can be any PromiseLike<T>
|
|
2096
|
-
* @returns Removed promise.
|
|
2097
|
-
*/
|
|
2098
|
-
remove(task) {
|
|
2099
|
-
const removedTask = this._buffer.splice(this._buffer.indexOf(task), 1)[0];
|
|
2100
|
-
return removedTask;
|
|
2101
|
-
}
|
|
2102
|
-
/**
|
|
2103
|
-
* This function returns the number of unresolved promises in the queue.
|
|
2104
|
-
*/
|
|
2105
|
-
length() {
|
|
2106
|
-
return this._buffer.length;
|
|
2107
|
-
}
|
|
2108
1981
|
/**
|
|
2109
1982
|
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
|
|
2110
1983
|
*
|
|
@@ -2114,8 +1987,12 @@ var Sentry = (function (exports) {
|
|
|
2114
1987
|
* @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
|
|
2115
1988
|
* `false` otherwise
|
|
2116
1989
|
*/
|
|
2117
|
-
drain(timeout) {
|
|
2118
|
-
return new SyncPromise(resolve => {
|
|
1990
|
+
function drain(timeout) {
|
|
1991
|
+
return new SyncPromise((resolve, reject) => {
|
|
1992
|
+
let counter = buffer.length;
|
|
1993
|
+
if (!counter) {
|
|
1994
|
+
return resolve(true);
|
|
1995
|
+
}
|
|
2119
1996
|
// wait for `timeout` ms and then resolve to `false` (if not cancelled first)
|
|
2120
1997
|
const capturedSetTimeout = setTimeout(() => {
|
|
2121
1998
|
if (timeout && timeout > 0) {
|
|
@@ -2123,16 +2000,62 @@ var Sentry = (function (exports) {
|
|
|
2123
2000
|
}
|
|
2124
2001
|
}, timeout);
|
|
2125
2002
|
// if all promises resolve in time, cancel the timer and resolve to `true`
|
|
2126
|
-
|
|
2127
|
-
.then(() => {
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2003
|
+
buffer.forEach(item => {
|
|
2004
|
+
void resolvedSyncPromise(item).then(() => {
|
|
2005
|
+
// eslint-disable-next-line no-plusplus
|
|
2006
|
+
if (!--counter) {
|
|
2007
|
+
clearTimeout(capturedSetTimeout);
|
|
2008
|
+
resolve(true);
|
|
2009
|
+
}
|
|
2010
|
+
}, reject);
|
|
2133
2011
|
});
|
|
2134
2012
|
});
|
|
2135
2013
|
}
|
|
2014
|
+
return {
|
|
2015
|
+
$: buffer,
|
|
2016
|
+
add,
|
|
2017
|
+
drain,
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
function isSupportedSeverity(level) {
|
|
2022
|
+
return SeverityLevels.indexOf(level) !== -1;
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Converts a string-based level into a {@link Severity}.
|
|
2026
|
+
*
|
|
2027
|
+
* @param level string representation of Severity
|
|
2028
|
+
* @returns Severity
|
|
2029
|
+
*/
|
|
2030
|
+
function severityFromString(level) {
|
|
2031
|
+
if (level === 'warn')
|
|
2032
|
+
return exports.Severity.Warning;
|
|
2033
|
+
if (isSupportedSeverity(level)) {
|
|
2034
|
+
return level;
|
|
2035
|
+
}
|
|
2036
|
+
return exports.Severity.Log;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* Converts an HTTP status code to sentry status {@link EventStatus}.
|
|
2041
|
+
*
|
|
2042
|
+
* @param code number HTTP status code
|
|
2043
|
+
* @returns EventStatus
|
|
2044
|
+
*/
|
|
2045
|
+
function eventStatusFromHttpCode(code) {
|
|
2046
|
+
if (code >= 200 && code < 300) {
|
|
2047
|
+
return 'success';
|
|
2048
|
+
}
|
|
2049
|
+
if (code === 429) {
|
|
2050
|
+
return 'rate_limit';
|
|
2051
|
+
}
|
|
2052
|
+
if (code >= 400 && code < 500) {
|
|
2053
|
+
return 'invalid';
|
|
2054
|
+
}
|
|
2055
|
+
if (code >= 500) {
|
|
2056
|
+
return 'failed';
|
|
2057
|
+
}
|
|
2058
|
+
return 'unknown';
|
|
2136
2059
|
}
|
|
2137
2060
|
|
|
2138
2061
|
/**
|
|
@@ -2291,6 +2214,11 @@ var Sentry = (function (exports) {
|
|
|
2291
2214
|
this._extra = {};
|
|
2292
2215
|
/** Contexts */
|
|
2293
2216
|
this._contexts = {};
|
|
2217
|
+
/**
|
|
2218
|
+
* A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
|
|
2219
|
+
* sent to Sentry
|
|
2220
|
+
*/
|
|
2221
|
+
this._sdkProcessingMetadata = {};
|
|
2294
2222
|
}
|
|
2295
2223
|
/**
|
|
2296
2224
|
* Inherit values from the parent scope.
|
|
@@ -2453,19 +2381,10 @@ var Sentry = (function (exports) {
|
|
|
2453
2381
|
* @inheritDoc
|
|
2454
2382
|
*/
|
|
2455
2383
|
getTransaction() {
|
|
2456
|
-
|
|
2457
|
-
//
|
|
2384
|
+
// Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
|
|
2385
|
+
// have a pointer to the currently-active transaction.
|
|
2458
2386
|
const span = this.getSpan();
|
|
2459
|
-
|
|
2460
|
-
if ((_a = span) === null || _a === void 0 ? void 0 : _a.transaction) {
|
|
2461
|
-
return (_b = span) === null || _b === void 0 ? void 0 : _b.transaction;
|
|
2462
|
-
}
|
|
2463
|
-
// fallback to the old way (known bug: this only finds transactions with sampled = true)
|
|
2464
|
-
if ((_d = (_c = span) === null || _c === void 0 ? void 0 : _c.spanRecorder) === null || _d === void 0 ? void 0 : _d.spans[0]) {
|
|
2465
|
-
return span.spanRecorder.spans[0];
|
|
2466
|
-
}
|
|
2467
|
-
// neither way found a transaction
|
|
2468
|
-
return undefined;
|
|
2387
|
+
return span && span.transaction;
|
|
2469
2388
|
}
|
|
2470
2389
|
/**
|
|
2471
2390
|
* @inheritDoc
|
|
@@ -2584,7 +2503,6 @@ var Sentry = (function (exports) {
|
|
|
2584
2503
|
* @hidden
|
|
2585
2504
|
*/
|
|
2586
2505
|
applyToEvent(event, hint) {
|
|
2587
|
-
var _a;
|
|
2588
2506
|
if (this._extra && Object.keys(this._extra).length) {
|
|
2589
2507
|
event.extra = Object.assign(Object.assign({}, this._extra), event.extra);
|
|
2590
2508
|
}
|
|
@@ -2608,7 +2526,7 @@ var Sentry = (function (exports) {
|
|
|
2608
2526
|
// errors with transaction and it relies on that.
|
|
2609
2527
|
if (this._span) {
|
|
2610
2528
|
event.contexts = Object.assign({ trace: this._span.getTraceContext() }, event.contexts);
|
|
2611
|
-
const transactionName =
|
|
2529
|
+
const transactionName = this._span.transaction && this._span.transaction.name;
|
|
2612
2530
|
if (transactionName) {
|
|
2613
2531
|
event.tags = Object.assign({ transaction: transactionName }, event.tags);
|
|
2614
2532
|
}
|
|
@@ -2616,8 +2534,16 @@ var Sentry = (function (exports) {
|
|
|
2616
2534
|
this._applyFingerprint(event);
|
|
2617
2535
|
event.breadcrumbs = [...(event.breadcrumbs || []), ...this._breadcrumbs];
|
|
2618
2536
|
event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
|
|
2537
|
+
event.sdkProcessingMetadata = this._sdkProcessingMetadata;
|
|
2619
2538
|
return this._notifyEventProcessors([...getGlobalEventProcessors(), ...this._eventProcessors], event, hint);
|
|
2620
2539
|
}
|
|
2540
|
+
/**
|
|
2541
|
+
* Add data which will be accessible during event processing but won't get sent to Sentry
|
|
2542
|
+
*/
|
|
2543
|
+
setSDKProcessingMetadata(newData) {
|
|
2544
|
+
this._sdkProcessingMetadata = Object.assign(Object.assign({}, this._sdkProcessingMetadata), newData);
|
|
2545
|
+
return this;
|
|
2546
|
+
}
|
|
2621
2547
|
/**
|
|
2622
2548
|
* This will be called after {@link applyToEvent} is finished.
|
|
2623
2549
|
*/
|
|
@@ -2705,7 +2631,7 @@ var Sentry = (function (exports) {
|
|
|
2705
2631
|
this.errors = 0;
|
|
2706
2632
|
this.sid = uuid4();
|
|
2707
2633
|
this.duration = 0;
|
|
2708
|
-
this.status =
|
|
2634
|
+
this.status = 'ok';
|
|
2709
2635
|
this.init = true;
|
|
2710
2636
|
this.ignoreDuration = false;
|
|
2711
2637
|
// Both timestamp and started are in seconds since the UNIX epoch.
|
|
@@ -2778,8 +2704,8 @@ var Sentry = (function (exports) {
|
|
|
2778
2704
|
if (status) {
|
|
2779
2705
|
this.update({ status });
|
|
2780
2706
|
}
|
|
2781
|
-
else if (this.status ===
|
|
2782
|
-
this.update({ status:
|
|
2707
|
+
else if (this.status === 'ok') {
|
|
2708
|
+
this.update({ status: 'exited' });
|
|
2783
2709
|
}
|
|
2784
2710
|
else {
|
|
2785
2711
|
this.update();
|
|
@@ -2797,17 +2723,16 @@ var Sentry = (function (exports) {
|
|
|
2797
2723
|
errors: this.errors,
|
|
2798
2724
|
did: typeof this.did === 'number' || typeof this.did === 'string' ? `${this.did}` : undefined,
|
|
2799
2725
|
duration: this.duration,
|
|
2800
|
-
attrs:
|
|
2726
|
+
attrs: {
|
|
2801
2727
|
release: this.release,
|
|
2802
2728
|
environment: this.environment,
|
|
2803
2729
|
ip_address: this.ipAddress,
|
|
2804
2730
|
user_agent: this.userAgent,
|
|
2805
|
-
}
|
|
2731
|
+
},
|
|
2806
2732
|
});
|
|
2807
2733
|
}
|
|
2808
2734
|
}
|
|
2809
2735
|
|
|
2810
|
-
/* eslint-disable max-lines */
|
|
2811
2736
|
/**
|
|
2812
2737
|
* API compatibility version of this hub.
|
|
2813
2738
|
*
|
|
@@ -3117,11 +3042,17 @@ var Sentry = (function (exports) {
|
|
|
3117
3042
|
* @inheritDoc
|
|
3118
3043
|
*/
|
|
3119
3044
|
endSession() {
|
|
3120
|
-
|
|
3121
|
-
|
|
3045
|
+
const layer = this.getStackTop();
|
|
3046
|
+
const scope = layer && layer.scope;
|
|
3047
|
+
const session = scope && scope.getSession();
|
|
3048
|
+
if (session) {
|
|
3049
|
+
session.close();
|
|
3050
|
+
}
|
|
3122
3051
|
this._sendSessionUpdate();
|
|
3123
3052
|
// the session is over; take it off of the scope
|
|
3124
|
-
|
|
3053
|
+
if (scope) {
|
|
3054
|
+
scope.setSession();
|
|
3055
|
+
}
|
|
3125
3056
|
}
|
|
3126
3057
|
/**
|
|
3127
3058
|
* @inheritDoc
|
|
@@ -3137,8 +3068,8 @@ var Sentry = (function (exports) {
|
|
|
3137
3068
|
if (scope) {
|
|
3138
3069
|
// End existing session if there's one
|
|
3139
3070
|
const currentSession = scope.getSession && scope.getSession();
|
|
3140
|
-
if (currentSession && currentSession.status ===
|
|
3141
|
-
currentSession.update({ status:
|
|
3071
|
+
if (currentSession && currentSession.status === 'ok') {
|
|
3072
|
+
currentSession.update({ status: 'exited' });
|
|
3142
3073
|
}
|
|
3143
3074
|
this.endSession();
|
|
3144
3075
|
// Afterwards we set the new session on the scope
|
|
@@ -3240,9 +3171,9 @@ var Sentry = (function (exports) {
|
|
|
3240
3171
|
* @returns discovered hub
|
|
3241
3172
|
*/
|
|
3242
3173
|
function getHubFromActiveDomain(registry) {
|
|
3243
|
-
var _a, _b, _c;
|
|
3244
3174
|
try {
|
|
3245
|
-
const
|
|
3175
|
+
const sentry = getMainCarrier().__SENTRY__;
|
|
3176
|
+
const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
|
|
3246
3177
|
// If there's no active domain, just return global hub
|
|
3247
3178
|
if (!activeDomain) {
|
|
3248
3179
|
return getHubFromCarrier(registry);
|
|
@@ -3333,7 +3264,7 @@ var Sentry = (function (exports) {
|
|
|
3333
3264
|
* Captures a message event and sends it to Sentry.
|
|
3334
3265
|
*
|
|
3335
3266
|
* @param message The message to send to Sentry.
|
|
3336
|
-
* @param
|
|
3267
|
+
* @param Severity Define the level of the message.
|
|
3337
3268
|
* @returns The generated eventId.
|
|
3338
3269
|
*/
|
|
3339
3270
|
function captureMessage(message, captureContext) {
|
|
@@ -3465,134 +3396,83 @@ var Sentry = (function (exports) {
|
|
|
3465
3396
|
}
|
|
3466
3397
|
|
|
3467
3398
|
const SENTRY_API_VERSION = '7';
|
|
3399
|
+
/** Initializes API Details */
|
|
3400
|
+
function initAPIDetails(dsn, metadata, tunnel) {
|
|
3401
|
+
return {
|
|
3402
|
+
initDsn: dsn,
|
|
3403
|
+
metadata: metadata || {},
|
|
3404
|
+
dsn: makeDsn(dsn),
|
|
3405
|
+
tunnel,
|
|
3406
|
+
};
|
|
3407
|
+
}
|
|
3408
|
+
/** Returns the prefix to construct Sentry ingestion API endpoints. */
|
|
3409
|
+
function getBaseApiEndpoint(dsn) {
|
|
3410
|
+
const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
|
|
3411
|
+
const port = dsn.port ? `:${dsn.port}` : '';
|
|
3412
|
+
return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
|
|
3413
|
+
}
|
|
3414
|
+
/** Returns the ingest API endpoint for target. */
|
|
3415
|
+
function _getIngestEndpoint(dsn, target) {
|
|
3416
|
+
return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/${target}/`;
|
|
3417
|
+
}
|
|
3418
|
+
/** Returns a URL-encoded string with auth config suitable for a query string. */
|
|
3419
|
+
function _encodedAuth(dsn) {
|
|
3420
|
+
return urlEncode({
|
|
3421
|
+
// We send only the minimum set of required information. See
|
|
3422
|
+
// https://github.com/getsentry/sentry-javascript/issues/2572.
|
|
3423
|
+
sentry_key: dsn.publicKey,
|
|
3424
|
+
sentry_version: SENTRY_API_VERSION,
|
|
3425
|
+
});
|
|
3426
|
+
}
|
|
3427
|
+
/** Returns the store endpoint URL. */
|
|
3428
|
+
function getStoreEndpoint(dsn) {
|
|
3429
|
+
return _getIngestEndpoint(dsn, 'store');
|
|
3430
|
+
}
|
|
3468
3431
|
/**
|
|
3469
|
-
*
|
|
3470
|
-
*
|
|
3471
|
-
*
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
/** Returns the store endpoint URL. */
|
|
3497
|
-
getStoreEndpoint() {
|
|
3498
|
-
return this._getIngestEndpoint('store');
|
|
3499
|
-
}
|
|
3500
|
-
/**
|
|
3501
|
-
* Returns the store endpoint URL with auth in the query string.
|
|
3502
|
-
*
|
|
3503
|
-
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3504
|
-
*/
|
|
3505
|
-
getStoreEndpointWithUrlEncodedAuth() {
|
|
3506
|
-
return `${this.getStoreEndpoint()}?${this._encodedAuth()}`;
|
|
3507
|
-
}
|
|
3508
|
-
/**
|
|
3509
|
-
* Returns the envelope endpoint URL with auth in the query string.
|
|
3510
|
-
*
|
|
3511
|
-
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3512
|
-
*/
|
|
3513
|
-
getEnvelopeEndpointWithUrlEncodedAuth() {
|
|
3514
|
-
if (this.forceEnvelope()) {
|
|
3515
|
-
return this._tunnel;
|
|
3516
|
-
}
|
|
3517
|
-
return `${this._getEnvelopeEndpoint()}?${this._encodedAuth()}`;
|
|
3518
|
-
}
|
|
3519
|
-
/** Returns only the path component for the store endpoint. */
|
|
3520
|
-
getStoreEndpointPath() {
|
|
3521
|
-
const dsn = this.getDsn();
|
|
3522
|
-
return `${dsn.path ? `/${dsn.path}` : ''}/api/${dsn.projectId}/store/`;
|
|
3523
|
-
}
|
|
3524
|
-
/**
|
|
3525
|
-
* Returns an object that can be used in request headers.
|
|
3526
|
-
* This is needed for node and the old /store endpoint in sentry
|
|
3527
|
-
*/
|
|
3528
|
-
getRequestHeaders(clientName, clientVersion) {
|
|
3529
|
-
// CHANGE THIS to use metadata but keep clientName and clientVersion compatible
|
|
3530
|
-
const dsn = this.getDsn();
|
|
3531
|
-
const header = [`Sentry sentry_version=${SENTRY_API_VERSION}`];
|
|
3532
|
-
header.push(`sentry_client=${clientName}/${clientVersion}`);
|
|
3533
|
-
header.push(`sentry_key=${dsn.publicKey}`);
|
|
3534
|
-
if (dsn.pass) {
|
|
3535
|
-
header.push(`sentry_secret=${dsn.pass}`);
|
|
3432
|
+
* Returns the store endpoint URL with auth in the query string.
|
|
3433
|
+
*
|
|
3434
|
+
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3435
|
+
*/
|
|
3436
|
+
function getStoreEndpointWithUrlEncodedAuth(dsn) {
|
|
3437
|
+
return `${getStoreEndpoint(dsn)}?${_encodedAuth(dsn)}`;
|
|
3438
|
+
}
|
|
3439
|
+
/** Returns the envelope endpoint URL. */
|
|
3440
|
+
function _getEnvelopeEndpoint(dsn) {
|
|
3441
|
+
return _getIngestEndpoint(dsn, 'envelope');
|
|
3442
|
+
}
|
|
3443
|
+
/**
|
|
3444
|
+
* Returns the envelope endpoint URL with auth in the query string.
|
|
3445
|
+
*
|
|
3446
|
+
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3447
|
+
*/
|
|
3448
|
+
function getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel) {
|
|
3449
|
+
return tunnel ? tunnel : `${_getEnvelopeEndpoint(dsn)}?${_encodedAuth(dsn)}`;
|
|
3450
|
+
}
|
|
3451
|
+
/** Returns the url to the report dialog endpoint. */
|
|
3452
|
+
function getReportDialogEndpoint(dsnLike, dialogOptions) {
|
|
3453
|
+
const dsn = makeDsn(dsnLike);
|
|
3454
|
+
const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
|
|
3455
|
+
let encodedOptions = `dsn=${dsnToString(dsn)}`;
|
|
3456
|
+
for (const key in dialogOptions) {
|
|
3457
|
+
if (key === 'dsn') {
|
|
3458
|
+
continue;
|
|
3536
3459
|
}
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
'X-Sentry-Auth': header.join(', '),
|
|
3540
|
-
};
|
|
3541
|
-
}
|
|
3542
|
-
/** Returns the url to the report dialog endpoint. */
|
|
3543
|
-
getReportDialogEndpoint(dialogOptions = {}) {
|
|
3544
|
-
const dsn = this.getDsn();
|
|
3545
|
-
const endpoint = `${this.getBaseApiEndpoint()}embed/error-page/`;
|
|
3546
|
-
const encodedOptions = [];
|
|
3547
|
-
encodedOptions.push(`dsn=${dsn.toString()}`);
|
|
3548
|
-
for (const key in dialogOptions) {
|
|
3549
|
-
if (key === 'dsn') {
|
|
3460
|
+
if (key === 'user') {
|
|
3461
|
+
if (!dialogOptions.user) {
|
|
3550
3462
|
continue;
|
|
3551
3463
|
}
|
|
3552
|
-
if (
|
|
3553
|
-
|
|
3554
|
-
continue;
|
|
3555
|
-
}
|
|
3556
|
-
if (dialogOptions.user.name) {
|
|
3557
|
-
encodedOptions.push(`name=${encodeURIComponent(dialogOptions.user.name)}`);
|
|
3558
|
-
}
|
|
3559
|
-
if (dialogOptions.user.email) {
|
|
3560
|
-
encodedOptions.push(`email=${encodeURIComponent(dialogOptions.user.email)}`);
|
|
3561
|
-
}
|
|
3464
|
+
if (dialogOptions.user.name) {
|
|
3465
|
+
encodedOptions += `&name=${encodeURIComponent(dialogOptions.user.name)}`;
|
|
3562
3466
|
}
|
|
3563
|
-
|
|
3564
|
-
encodedOptions
|
|
3467
|
+
if (dialogOptions.user.email) {
|
|
3468
|
+
encodedOptions += `&email=${encodeURIComponent(dialogOptions.user.email)}`;
|
|
3565
3469
|
}
|
|
3566
3470
|
}
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
}
|
|
3570
|
-
return endpoint;
|
|
3571
|
-
}
|
|
3572
|
-
/** Returns the envelope endpoint URL. */
|
|
3573
|
-
_getEnvelopeEndpoint() {
|
|
3574
|
-
return this._getIngestEndpoint('envelope');
|
|
3575
|
-
}
|
|
3576
|
-
/** Returns the ingest API endpoint for target. */
|
|
3577
|
-
_getIngestEndpoint(target) {
|
|
3578
|
-
if (this._tunnel) {
|
|
3579
|
-
return this._tunnel;
|
|
3471
|
+
else {
|
|
3472
|
+
encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key])}`;
|
|
3580
3473
|
}
|
|
3581
|
-
const base = this.getBaseApiEndpoint();
|
|
3582
|
-
const dsn = this.getDsn();
|
|
3583
|
-
return `${base}${dsn.projectId}/${target}/`;
|
|
3584
|
-
}
|
|
3585
|
-
/** Returns a URL-encoded string with auth config suitable for a query string. */
|
|
3586
|
-
_encodedAuth() {
|
|
3587
|
-
const dsn = this.getDsn();
|
|
3588
|
-
const auth = {
|
|
3589
|
-
// We send only the minimum set of required information. See
|
|
3590
|
-
// https://github.com/getsentry/sentry-javascript/issues/2572.
|
|
3591
|
-
sentry_key: dsn.publicKey,
|
|
3592
|
-
sentry_version: SENTRY_API_VERSION,
|
|
3593
|
-
};
|
|
3594
|
-
return urlEncode(auth);
|
|
3595
3474
|
}
|
|
3475
|
+
return `${endpoint}?${encodedOptions}`;
|
|
3596
3476
|
}
|
|
3597
3477
|
|
|
3598
3478
|
const installedIntegrations = [];
|
|
@@ -3656,7 +3536,7 @@ var Sentry = (function (exports) {
|
|
|
3656
3536
|
// set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty`
|
|
3657
3537
|
// because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be
|
|
3658
3538
|
// considered a member of the index the way the actual integrations are
|
|
3659
|
-
|
|
3539
|
+
addNonEnumerableProperty(integrations, 'initialized', true);
|
|
3660
3540
|
return integrations;
|
|
3661
3541
|
}
|
|
3662
3542
|
|
|
@@ -3709,7 +3589,7 @@ var Sentry = (function (exports) {
|
|
|
3709
3589
|
this._backend = new backendClass(options);
|
|
3710
3590
|
this._options = options;
|
|
3711
3591
|
if (options.dsn) {
|
|
3712
|
-
this._dsn =
|
|
3592
|
+
this._dsn = makeDsn(options.dsn);
|
|
3713
3593
|
}
|
|
3714
3594
|
}
|
|
3715
3595
|
/**
|
|
@@ -3750,9 +3630,8 @@ var Sentry = (function (exports) {
|
|
|
3750
3630
|
* @inheritDoc
|
|
3751
3631
|
*/
|
|
3752
3632
|
captureEvent(event, hint, scope) {
|
|
3753
|
-
var _a;
|
|
3754
3633
|
// ensure we haven't captured this very object before
|
|
3755
|
-
if (
|
|
3634
|
+
if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {
|
|
3756
3635
|
logger.log(ALREADY_SEEN_ERROR);
|
|
3757
3636
|
return;
|
|
3758
3637
|
}
|
|
@@ -3767,11 +3646,15 @@ var Sentry = (function (exports) {
|
|
|
3767
3646
|
*/
|
|
3768
3647
|
captureSession(session) {
|
|
3769
3648
|
if (!this._isEnabled()) {
|
|
3770
|
-
|
|
3649
|
+
if (isDebugBuild()) {
|
|
3650
|
+
logger.warn('SDK not enabled, will not capture session.');
|
|
3651
|
+
}
|
|
3771
3652
|
return;
|
|
3772
3653
|
}
|
|
3773
3654
|
if (!(typeof session.release === 'string')) {
|
|
3774
|
-
|
|
3655
|
+
if (isDebugBuild()) {
|
|
3656
|
+
logger.warn('Discarded session because of missing or non-string release');
|
|
3657
|
+
}
|
|
3775
3658
|
}
|
|
3776
3659
|
else {
|
|
3777
3660
|
this._sendSession(session);
|
|
@@ -3854,10 +3737,10 @@ var Sentry = (function (exports) {
|
|
|
3854
3737
|
// A session is updated and that session update is sent in only one of the two following scenarios:
|
|
3855
3738
|
// 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
|
|
3856
3739
|
// 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
|
|
3857
|
-
const sessionNonTerminal = session.status ===
|
|
3740
|
+
const sessionNonTerminal = session.status === 'ok';
|
|
3858
3741
|
const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
|
|
3859
3742
|
if (shouldUpdateAndSend) {
|
|
3860
|
-
session.update(Object.assign(Object.assign({}, (crashed && { status:
|
|
3743
|
+
session.update(Object.assign(Object.assign({}, (crashed && { status: 'crashed' })), { errors: session.errors || Number(errored || crashed) }));
|
|
3861
3744
|
this.captureSession(session);
|
|
3862
3745
|
}
|
|
3863
3746
|
}
|
|
@@ -3928,7 +3811,7 @@ var Sentry = (function (exports) {
|
|
|
3928
3811
|
finalScope = Scope.clone(finalScope).update(hint.captureContext);
|
|
3929
3812
|
}
|
|
3930
3813
|
// We prepare the result here with a resolved Event.
|
|
3931
|
-
let result =
|
|
3814
|
+
let result = resolvedSyncPromise(prepared);
|
|
3932
3815
|
// This should be the last thing called, since we want that
|
|
3933
3816
|
// {@link Hub.addEventProcessor} gets the finished prepared event.
|
|
3934
3817
|
if (finalScope) {
|
|
@@ -3978,10 +3861,7 @@ var Sentry = (function (exports) {
|
|
|
3978
3861
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
3979
3862
|
normalized.contexts.trace = event.contexts.trace;
|
|
3980
3863
|
}
|
|
3981
|
-
|
|
3982
|
-
if (_experiments.ensureNoCircularStructures) {
|
|
3983
|
-
return normalize(normalized);
|
|
3984
|
-
}
|
|
3864
|
+
event.sdkProcessingMetadata = Object.assign(Object.assign({}, event.sdkProcessingMetadata), { baseClientNormalized: true });
|
|
3985
3865
|
return normalized;
|
|
3986
3866
|
}
|
|
3987
3867
|
/**
|
|
@@ -4060,26 +3940,29 @@ var Sentry = (function (exports) {
|
|
|
4060
3940
|
* @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
|
|
4061
3941
|
*/
|
|
4062
3942
|
_processEvent(event, hint, scope) {
|
|
4063
|
-
var _a, _b;
|
|
4064
3943
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
4065
3944
|
const { beforeSend, sampleRate } = this.getOptions();
|
|
4066
3945
|
const transport = this.getTransport();
|
|
3946
|
+
function recordLostEvent(outcome, category) {
|
|
3947
|
+
if (transport.recordLostEvent) {
|
|
3948
|
+
transport.recordLostEvent(outcome, category);
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
4067
3951
|
if (!this._isEnabled()) {
|
|
4068
|
-
return
|
|
3952
|
+
return rejectedSyncPromise(new SentryError('SDK not enabled, will not capture event.'));
|
|
4069
3953
|
}
|
|
4070
3954
|
const isTransaction = event.type === 'transaction';
|
|
4071
3955
|
// 1.0 === 100% events are sent
|
|
4072
3956
|
// 0.0 === 0% events are sent
|
|
4073
3957
|
// Sampling for transaction happens somewhere else
|
|
4074
3958
|
if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) {
|
|
4075
|
-
|
|
4076
|
-
return
|
|
3959
|
+
recordLostEvent('sample_rate', 'event');
|
|
3960
|
+
return rejectedSyncPromise(new SentryError(`Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`));
|
|
4077
3961
|
}
|
|
4078
3962
|
return this._prepareEvent(event, scope, hint)
|
|
4079
3963
|
.then(prepared => {
|
|
4080
|
-
var _a, _b;
|
|
4081
3964
|
if (prepared === null) {
|
|
4082
|
-
|
|
3965
|
+
recordLostEvent('event_processor', event.type || 'event');
|
|
4083
3966
|
throw new SentryError('An event processor returned null, will not send event.');
|
|
4084
3967
|
}
|
|
4085
3968
|
const isInternalException = hint && hint.data && hint.data.__sentry__ === true;
|
|
@@ -4087,12 +3970,11 @@ var Sentry = (function (exports) {
|
|
|
4087
3970
|
return prepared;
|
|
4088
3971
|
}
|
|
4089
3972
|
const beforeSendResult = beforeSend(prepared, hint);
|
|
4090
|
-
return
|
|
3973
|
+
return _ensureBeforeSendRv(beforeSendResult);
|
|
4091
3974
|
})
|
|
4092
3975
|
.then(processedEvent => {
|
|
4093
|
-
var _a, _b;
|
|
4094
3976
|
if (processedEvent === null) {
|
|
4095
|
-
|
|
3977
|
+
recordLostEvent('before_send', event.type || 'event');
|
|
4096
3978
|
throw new SentryError('`beforeSend` returned `null`, will not send event.');
|
|
4097
3979
|
}
|
|
4098
3980
|
const session = scope && scope.getSession && scope.getSession();
|
|
@@ -4128,26 +4010,26 @@ var Sentry = (function (exports) {
|
|
|
4128
4010
|
return reason;
|
|
4129
4011
|
});
|
|
4130
4012
|
}
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
});
|
|
4145
|
-
}
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
return rv;
|
|
4013
|
+
}
|
|
4014
|
+
/**
|
|
4015
|
+
* Verifies that return value of configured `beforeSend` is of expected type.
|
|
4016
|
+
*/
|
|
4017
|
+
function _ensureBeforeSendRv(rv) {
|
|
4018
|
+
const nullErr = '`beforeSend` method has to return `null` or a valid event.';
|
|
4019
|
+
if (isThenable(rv)) {
|
|
4020
|
+
return rv.then(event => {
|
|
4021
|
+
if (!(isPlainObject(event) || event === null)) {
|
|
4022
|
+
throw new SentryError(nullErr);
|
|
4023
|
+
}
|
|
4024
|
+
return event;
|
|
4025
|
+
}, e => {
|
|
4026
|
+
throw new SentryError(`beforeSend rejected with ${e}`);
|
|
4027
|
+
});
|
|
4028
|
+
}
|
|
4029
|
+
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4030
|
+
throw new SentryError(nullErr);
|
|
4150
4031
|
}
|
|
4032
|
+
return rv;
|
|
4151
4033
|
}
|
|
4152
4034
|
|
|
4153
4035
|
/** Noop transport */
|
|
@@ -4156,16 +4038,16 @@ var Sentry = (function (exports) {
|
|
|
4156
4038
|
* @inheritDoc
|
|
4157
4039
|
*/
|
|
4158
4040
|
sendEvent(_) {
|
|
4159
|
-
return
|
|
4041
|
+
return resolvedSyncPromise({
|
|
4160
4042
|
reason: `NoopTransport: Event has been skipped because no Dsn is configured.`,
|
|
4161
|
-
status:
|
|
4043
|
+
status: 'skipped',
|
|
4162
4044
|
});
|
|
4163
4045
|
}
|
|
4164
4046
|
/**
|
|
4165
4047
|
* @inheritDoc
|
|
4166
4048
|
*/
|
|
4167
4049
|
close(_) {
|
|
4168
|
-
return
|
|
4050
|
+
return resolvedSyncPromise(true);
|
|
4169
4051
|
}
|
|
4170
4052
|
}
|
|
4171
4053
|
|
|
@@ -4200,7 +4082,9 @@ var Sentry = (function (exports) {
|
|
|
4200
4082
|
*/
|
|
4201
4083
|
sendEvent(event) {
|
|
4202
4084
|
void this._transport.sendEvent(event).then(null, reason => {
|
|
4203
|
-
|
|
4085
|
+
if (isDebugBuild()) {
|
|
4086
|
+
logger.error(`Error while sending event: ${reason}`);
|
|
4087
|
+
}
|
|
4204
4088
|
});
|
|
4205
4089
|
}
|
|
4206
4090
|
/**
|
|
@@ -4208,11 +4092,15 @@ var Sentry = (function (exports) {
|
|
|
4208
4092
|
*/
|
|
4209
4093
|
sendSession(session) {
|
|
4210
4094
|
if (!this._transport.sendSession) {
|
|
4211
|
-
|
|
4095
|
+
if (isDebugBuild()) {
|
|
4096
|
+
logger.warn("Dropping session because custom transport doesn't implement sendSession");
|
|
4097
|
+
}
|
|
4212
4098
|
return;
|
|
4213
4099
|
}
|
|
4214
4100
|
void this._transport.sendSession(session).then(null, reason => {
|
|
4215
|
-
|
|
4101
|
+
if (isDebugBuild()) {
|
|
4102
|
+
logger.error(`Error while sending session: ${reason}`);
|
|
4103
|
+
}
|
|
4216
4104
|
});
|
|
4217
4105
|
}
|
|
4218
4106
|
/**
|
|
@@ -4229,31 +4117,6 @@ var Sentry = (function (exports) {
|
|
|
4229
4117
|
}
|
|
4230
4118
|
}
|
|
4231
4119
|
|
|
4232
|
-
/*! *****************************************************************************
|
|
4233
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4234
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
4235
|
-
this file except in compliance with the License. You may obtain a copy of the
|
|
4236
|
-
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4237
|
-
|
|
4238
|
-
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
4239
|
-
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
4240
|
-
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
4241
|
-
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
4242
|
-
|
|
4243
|
-
See the Apache Version 2.0 License for specific language governing permissions
|
|
4244
|
-
and limitations under the License.
|
|
4245
|
-
***************************************************************************** */
|
|
4246
|
-
|
|
4247
|
-
function __rest(s, e) {
|
|
4248
|
-
var t = {};
|
|
4249
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4250
|
-
t[p] = s[p];
|
|
4251
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
4252
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
|
4253
|
-
t[p[i]] = s[p[i]];
|
|
4254
|
-
return t;
|
|
4255
|
-
}
|
|
4256
|
-
|
|
4257
4120
|
/** Extract sdk info from from the API metadata */
|
|
4258
4121
|
function getSdkMetadataForEnvelopeHeader(api) {
|
|
4259
4122
|
if (!api.metadata || !api.metadata.sdk) {
|
|
@@ -4280,7 +4143,7 @@ var Sentry = (function (exports) {
|
|
|
4280
4143
|
/** Creates a SentryRequest from a Session. */
|
|
4281
4144
|
function sessionToSentryRequest(session, api) {
|
|
4282
4145
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4283
|
-
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.
|
|
4146
|
+
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
|
|
4284
4147
|
// I know this is hacky but we don't want to add `session` to request type since it's never rate limited
|
|
4285
4148
|
const type = 'aggregates' in session ? 'sessions' : 'session';
|
|
4286
4149
|
const itemHeaders = JSON.stringify({
|
|
@@ -4289,26 +4152,70 @@ var Sentry = (function (exports) {
|
|
|
4289
4152
|
return {
|
|
4290
4153
|
body: `${envelopeHeaders}\n${itemHeaders}\n${JSON.stringify(session)}`,
|
|
4291
4154
|
type,
|
|
4292
|
-
url: api.
|
|
4155
|
+
url: getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel),
|
|
4293
4156
|
};
|
|
4294
4157
|
}
|
|
4295
4158
|
/** Creates a SentryRequest from an event. */
|
|
4296
4159
|
function eventToSentryRequest(event, api) {
|
|
4297
4160
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4298
4161
|
const eventType = event.type || 'event';
|
|
4299
|
-
const useEnvelope = eventType === 'transaction' || api.
|
|
4300
|
-
const
|
|
4162
|
+
const useEnvelope = eventType === 'transaction' || !!api.tunnel;
|
|
4163
|
+
const { transactionSampling } = event.sdkProcessingMetadata || {};
|
|
4301
4164
|
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
|
|
4302
|
-
|
|
4303
|
-
|
|
4165
|
+
// TODO: Below is a temporary hack in order to debug a serialization error - see
|
|
4166
|
+
// https://github.com/getsentry/sentry-javascript/issues/2809 and
|
|
4167
|
+
// https://github.com/getsentry/sentry-javascript/pull/4425. TL;DR: even though we normalize all events (which should
|
|
4168
|
+
// prevent this), something is causing `JSON.stringify` to throw a circular reference error.
|
|
4169
|
+
//
|
|
4170
|
+
// When it's time to remove it:
|
|
4171
|
+
// 1. Delete everything between here and where the request object `req` is created, EXCEPT the line deleting
|
|
4172
|
+
// `sdkProcessingMetadata`
|
|
4173
|
+
// 2. Restore the original version of the request body, which is commented out
|
|
4174
|
+
// 3. Search for `skippedNormalization` and pull out the companion hack in the browser playwright tests
|
|
4175
|
+
enhanceEventWithSdkInfo(event, api.metadata.sdk);
|
|
4176
|
+
event.tags = event.tags || {};
|
|
4177
|
+
event.extra = event.extra || {};
|
|
4178
|
+
// In theory, all events should be marked as having gone through normalization and so
|
|
4179
|
+
// we should never set this tag
|
|
4180
|
+
if (!(event.sdkProcessingMetadata && event.sdkProcessingMetadata.baseClientNormalized)) {
|
|
4181
|
+
event.tags.skippedNormalization = true;
|
|
4182
|
+
}
|
|
4183
|
+
// prevent this data from being sent to sentry
|
|
4184
|
+
// TODO: This is NOT part of the hack - DO NOT DELETE
|
|
4185
|
+
delete event.sdkProcessingMetadata;
|
|
4186
|
+
let body;
|
|
4187
|
+
try {
|
|
4188
|
+
// 99.9% of events should get through just fine - no change in behavior for them
|
|
4189
|
+
body = JSON.stringify(event);
|
|
4304
4190
|
}
|
|
4305
|
-
|
|
4306
|
-
event
|
|
4191
|
+
catch (err) {
|
|
4192
|
+
// Record data about the error without replacing original event data, then force renormalization
|
|
4193
|
+
event.tags.JSONStringifyError = true;
|
|
4194
|
+
event.extra.JSONStringifyError = err;
|
|
4195
|
+
try {
|
|
4196
|
+
body = JSON.stringify(normalize(event));
|
|
4197
|
+
}
|
|
4198
|
+
catch (newErr) {
|
|
4199
|
+
// At this point even renormalization hasn't worked, meaning something about the event data has gone very wrong.
|
|
4200
|
+
// Time to cut our losses and record only the new error. With luck, even in the problematic cases we're trying to
|
|
4201
|
+
// debug with this hack, we won't ever land here.
|
|
4202
|
+
const innerErr = newErr;
|
|
4203
|
+
body = JSON.stringify({
|
|
4204
|
+
message: 'JSON.stringify error after renormalization',
|
|
4205
|
+
// setting `extra: { innerErr }` here for some reason results in an empty object, so unpack manually
|
|
4206
|
+
extra: { message: innerErr.message, stack: innerErr.stack },
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4307
4209
|
}
|
|
4308
4210
|
const req = {
|
|
4309
|
-
|
|
4211
|
+
// this is the relevant line of code before the hack was added, to make it easy to undo said hack once we've solved
|
|
4212
|
+
// the mystery
|
|
4213
|
+
// body: JSON.stringify(sdkInfo ? enhanceEventWithSdkInfo(event, api.metadata.sdk) : event),
|
|
4214
|
+
body,
|
|
4310
4215
|
type: eventType,
|
|
4311
|
-
url: useEnvelope
|
|
4216
|
+
url: useEnvelope
|
|
4217
|
+
? getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel)
|
|
4218
|
+
: getStoreEndpointWithUrlEncodedAuth(api.dsn),
|
|
4312
4219
|
};
|
|
4313
4220
|
// https://develop.sentry.dev/sdk/envelopes/
|
|
4314
4221
|
// Since we don't need to manipulate envelopes nor store them, there is no
|
|
@@ -4316,7 +4223,7 @@ var Sentry = (function (exports) {
|
|
|
4316
4223
|
// deserialization. Instead, we only implement a minimal subset of the spec to
|
|
4317
4224
|
// serialize events inline here.
|
|
4318
4225
|
if (useEnvelope) {
|
|
4319
|
-
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.
|
|
4226
|
+
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
|
|
4320
4227
|
const itemHeaders = JSON.stringify({
|
|
4321
4228
|
type: eventType,
|
|
4322
4229
|
// TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
|
|
@@ -4341,17 +4248,19 @@ var Sentry = (function (exports) {
|
|
|
4341
4248
|
* @param options Options to pass to the client.
|
|
4342
4249
|
*/
|
|
4343
4250
|
function initAndBind(clientClass, options) {
|
|
4344
|
-
var _a;
|
|
4345
4251
|
if (options.debug === true) {
|
|
4346
4252
|
logger.enable();
|
|
4347
4253
|
}
|
|
4348
4254
|
const hub = getCurrentHub();
|
|
4349
|
-
|
|
4255
|
+
const scope = hub.getScope();
|
|
4256
|
+
if (scope) {
|
|
4257
|
+
scope.update(options.initialScope);
|
|
4258
|
+
}
|
|
4350
4259
|
const client = new clientClass(options);
|
|
4351
4260
|
hub.bindClient(client);
|
|
4352
4261
|
}
|
|
4353
4262
|
|
|
4354
|
-
const SDK_VERSION = '6.
|
|
4263
|
+
const SDK_VERSION = '6.17.2';
|
|
4355
4264
|
|
|
4356
4265
|
let originalFunctionToString;
|
|
4357
4266
|
/** Patch toString calls to return proper name for wrapped functions */
|
|
@@ -4370,7 +4279,7 @@ var Sentry = (function (exports) {
|
|
|
4370
4279
|
originalFunctionToString = Function.prototype.toString;
|
|
4371
4280
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4372
4281
|
Function.prototype.toString = function (...args) {
|
|
4373
|
-
const context = this
|
|
4282
|
+
const context = getOriginalFunction(this) || this;
|
|
4374
4283
|
return originalFunctionToString.apply(context, args);
|
|
4375
4284
|
};
|
|
4376
4285
|
}
|
|
@@ -4422,19 +4331,27 @@ var Sentry = (function (exports) {
|
|
|
4422
4331
|
/** JSDoc */
|
|
4423
4332
|
_shouldDropEvent(event, options) {
|
|
4424
4333
|
if (this._isSentryError(event, options)) {
|
|
4425
|
-
|
|
4334
|
+
if (isDebugBuild()) {
|
|
4335
|
+
logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
|
|
4336
|
+
}
|
|
4426
4337
|
return true;
|
|
4427
4338
|
}
|
|
4428
4339
|
if (this._isIgnoredError(event, options)) {
|
|
4429
|
-
|
|
4340
|
+
if (isDebugBuild()) {
|
|
4341
|
+
logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
|
|
4342
|
+
}
|
|
4430
4343
|
return true;
|
|
4431
4344
|
}
|
|
4432
4345
|
if (this._isDeniedUrl(event, options)) {
|
|
4433
|
-
|
|
4346
|
+
if (isDebugBuild()) {
|
|
4347
|
+
logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4348
|
+
}
|
|
4434
4349
|
return true;
|
|
4435
4350
|
}
|
|
4436
4351
|
if (!this._isAllowedUrl(event, options)) {
|
|
4437
|
-
|
|
4352
|
+
if (isDebugBuild()) {
|
|
4353
|
+
logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4354
|
+
}
|
|
4438
4355
|
return true;
|
|
4439
4356
|
}
|
|
4440
4357
|
return false;
|
|
@@ -4445,16 +4362,14 @@ var Sentry = (function (exports) {
|
|
|
4445
4362
|
return false;
|
|
4446
4363
|
}
|
|
4447
4364
|
try {
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
event.exception.values[0] &&
|
|
4452
|
-
event.exception.values[0].type === 'SentryError') ||
|
|
4453
|
-
false);
|
|
4365
|
+
// @ts-ignore can't be a sentry error if undefined
|
|
4366
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
4367
|
+
return event.exception.values[0].type === 'SentryError';
|
|
4454
4368
|
}
|
|
4455
|
-
catch (
|
|
4456
|
-
|
|
4369
|
+
catch (e) {
|
|
4370
|
+
// ignore
|
|
4457
4371
|
}
|
|
4372
|
+
return false;
|
|
4458
4373
|
}
|
|
4459
4374
|
/** JSDoc */
|
|
4460
4375
|
_isIgnoredError(event, options) {
|
|
@@ -4521,7 +4436,9 @@ var Sentry = (function (exports) {
|
|
|
4521
4436
|
return [`${value}`, `${type}: ${value}`];
|
|
4522
4437
|
}
|
|
4523
4438
|
catch (oO) {
|
|
4524
|
-
|
|
4439
|
+
if (isDebugBuild()) {
|
|
4440
|
+
logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
|
|
4441
|
+
}
|
|
4525
4442
|
return [];
|
|
4526
4443
|
}
|
|
4527
4444
|
}
|
|
@@ -4529,10 +4446,9 @@ var Sentry = (function (exports) {
|
|
|
4529
4446
|
}
|
|
4530
4447
|
/** JSDoc */
|
|
4531
4448
|
_getLastValidUrl(frames = []) {
|
|
4532
|
-
var _a, _b;
|
|
4533
4449
|
for (let i = frames.length - 1; i >= 0; i--) {
|
|
4534
4450
|
const frame = frames[i];
|
|
4535
|
-
if (
|
|
4451
|
+
if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
|
|
4536
4452
|
return frame.filename || null;
|
|
4537
4453
|
}
|
|
4538
4454
|
}
|
|
@@ -4542,17 +4458,22 @@ var Sentry = (function (exports) {
|
|
|
4542
4458
|
_getEventFilterUrl(event) {
|
|
4543
4459
|
try {
|
|
4544
4460
|
if (event.stacktrace) {
|
|
4545
|
-
|
|
4546
|
-
|
|
4461
|
+
return this._getLastValidUrl(event.stacktrace.frames);
|
|
4462
|
+
}
|
|
4463
|
+
let frames;
|
|
4464
|
+
try {
|
|
4465
|
+
// @ts-ignore we only care about frames if the whole thing here is defined
|
|
4466
|
+
frames = event.exception.values[0].stacktrace.frames;
|
|
4547
4467
|
}
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
return this._getLastValidUrl(frames);
|
|
4468
|
+
catch (e) {
|
|
4469
|
+
// ignore
|
|
4551
4470
|
}
|
|
4552
|
-
return null;
|
|
4471
|
+
return frames ? this._getLastValidUrl(frames) : null;
|
|
4553
4472
|
}
|
|
4554
4473
|
catch (oO) {
|
|
4555
|
-
|
|
4474
|
+
if (isDebugBuild()) {
|
|
4475
|
+
logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
|
|
4476
|
+
}
|
|
4556
4477
|
return null;
|
|
4557
4478
|
}
|
|
4558
4479
|
}
|
|
@@ -4914,7 +4835,7 @@ var Sentry = (function (exports) {
|
|
|
4914
4835
|
}
|
|
4915
4836
|
|
|
4916
4837
|
/**
|
|
4917
|
-
*
|
|
4838
|
+
* Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
|
|
4918
4839
|
* @hidden
|
|
4919
4840
|
*/
|
|
4920
4841
|
function eventFromException(options, exception, hint) {
|
|
@@ -4927,7 +4848,7 @@ var Sentry = (function (exports) {
|
|
|
4927
4848
|
if (hint && hint.event_id) {
|
|
4928
4849
|
event.event_id = hint.event_id;
|
|
4929
4850
|
}
|
|
4930
|
-
return
|
|
4851
|
+
return resolvedSyncPromise(event);
|
|
4931
4852
|
}
|
|
4932
4853
|
/**
|
|
4933
4854
|
* Builds and Event from a Message
|
|
@@ -4942,7 +4863,7 @@ var Sentry = (function (exports) {
|
|
|
4942
4863
|
if (hint && hint.event_id) {
|
|
4943
4864
|
event.event_id = hint.event_id;
|
|
4944
4865
|
}
|
|
4945
|
-
return
|
|
4866
|
+
return resolvedSyncPromise(event);
|
|
4946
4867
|
}
|
|
4947
4868
|
/**
|
|
4948
4869
|
* @hidden
|
|
@@ -4986,11 +4907,11 @@ var Sentry = (function (exports) {
|
|
|
4986
4907
|
return event;
|
|
4987
4908
|
}
|
|
4988
4909
|
if (isPlainObject(exception) || isEvent(exception)) {
|
|
4989
|
-
// If it
|
|
4990
|
-
// This will allow us to group events based on top-level keys
|
|
4991
|
-
//
|
|
4910
|
+
// If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
|
|
4911
|
+
// it manually. This will allow us to group events based on top-level keys which is much better than creating a new
|
|
4912
|
+
// group on any key/value change.
|
|
4992
4913
|
const objectException = exception;
|
|
4993
|
-
event = eventFromPlainObject(objectException, syntheticException, options.
|
|
4914
|
+
event = eventFromPlainObject(objectException, syntheticException, options.isRejection);
|
|
4994
4915
|
addExceptionMechanism(event, {
|
|
4995
4916
|
synthetic: true,
|
|
4996
4917
|
});
|
|
@@ -5070,7 +4991,6 @@ var Sentry = (function (exports) {
|
|
|
5070
4991
|
* Safari: resource blocked by content blocker
|
|
5071
4992
|
*/
|
|
5072
4993
|
function getNativeFetchImplementation() {
|
|
5073
|
-
var _a, _b;
|
|
5074
4994
|
if (cachedFetchImpl) {
|
|
5075
4995
|
return cachedFetchImpl;
|
|
5076
4996
|
}
|
|
@@ -5082,18 +5002,21 @@ var Sentry = (function (exports) {
|
|
|
5082
5002
|
const document = global$3.document;
|
|
5083
5003
|
let fetchImpl = global$3.fetch;
|
|
5084
5004
|
// eslint-disable-next-line deprecation/deprecation
|
|
5085
|
-
if (
|
|
5005
|
+
if (document && typeof document.createElement === `function`) {
|
|
5086
5006
|
try {
|
|
5087
5007
|
const sandbox = document.createElement('iframe');
|
|
5088
5008
|
sandbox.hidden = true;
|
|
5089
5009
|
document.head.appendChild(sandbox);
|
|
5090
|
-
|
|
5091
|
-
|
|
5010
|
+
const contentWindow = sandbox.contentWindow;
|
|
5011
|
+
if (contentWindow && contentWindow.fetch) {
|
|
5012
|
+
fetchImpl = contentWindow.fetch;
|
|
5092
5013
|
}
|
|
5093
5014
|
document.head.removeChild(sandbox);
|
|
5094
5015
|
}
|
|
5095
5016
|
catch (e) {
|
|
5096
|
-
|
|
5017
|
+
if (isDebugBuild()) {
|
|
5018
|
+
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
|
|
5019
|
+
}
|
|
5097
5020
|
}
|
|
5098
5021
|
}
|
|
5099
5022
|
return (cachedFetchImpl = fetchImpl.bind(global$3));
|
|
@@ -5124,25 +5047,23 @@ var Sentry = (function (exports) {
|
|
|
5124
5047
|
}
|
|
5125
5048
|
}
|
|
5126
5049
|
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
attachment: 'attachment',
|
|
5132
|
-
};
|
|
5050
|
+
function requestTypeToCategory(ty) {
|
|
5051
|
+
const tyStr = ty;
|
|
5052
|
+
return tyStr === 'event' ? 'error' : tyStr;
|
|
5053
|
+
}
|
|
5133
5054
|
const global$4 = getGlobalObject();
|
|
5134
5055
|
/** Base Transport class implementation */
|
|
5135
5056
|
class BaseTransport {
|
|
5136
5057
|
constructor(options) {
|
|
5137
5058
|
this.options = options;
|
|
5138
5059
|
/** A simple buffer holding all requests. */
|
|
5139
|
-
this._buffer =
|
|
5060
|
+
this._buffer = makePromiseBuffer(30);
|
|
5140
5061
|
/** Locks transport after receiving rate limits in a response */
|
|
5141
5062
|
this._rateLimits = {};
|
|
5142
5063
|
this._outcomes = {};
|
|
5143
|
-
this._api =
|
|
5064
|
+
this._api = initAPIDetails(options.dsn, options._metadata, options.tunnel);
|
|
5144
5065
|
// eslint-disable-next-line deprecation/deprecation
|
|
5145
|
-
this.url = this._api.
|
|
5066
|
+
this.url = getStoreEndpointWithUrlEncodedAuth(this._api.dsn);
|
|
5146
5067
|
if (this.options.sendClientReports && global$4.document) {
|
|
5147
5068
|
global$4.document.addEventListener('visibilitychange', () => {
|
|
5148
5069
|
if (global$4.document.visibilityState === 'hidden') {
|
|
@@ -5154,8 +5075,14 @@ var Sentry = (function (exports) {
|
|
|
5154
5075
|
/**
|
|
5155
5076
|
* @inheritDoc
|
|
5156
5077
|
*/
|
|
5157
|
-
sendEvent(
|
|
5158
|
-
|
|
5078
|
+
sendEvent(event) {
|
|
5079
|
+
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5080
|
+
}
|
|
5081
|
+
/**
|
|
5082
|
+
* @inheritDoc
|
|
5083
|
+
*/
|
|
5084
|
+
sendSession(session) {
|
|
5085
|
+
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5159
5086
|
}
|
|
5160
5087
|
/**
|
|
5161
5088
|
* @inheritDoc
|
|
@@ -5176,7 +5103,7 @@ var Sentry = (function (exports) {
|
|
|
5176
5103
|
// We could use nested maps, but it's much easier to read and type this way.
|
|
5177
5104
|
// A correct type for map-based implementation if we want to go that route
|
|
5178
5105
|
// would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
|
|
5179
|
-
const key = `${
|
|
5106
|
+
const key = `${requestTypeToCategory(category)}:${reason}`;
|
|
5180
5107
|
logger.log(`Adding outcome: ${key}`);
|
|
5181
5108
|
this._outcomes[key] = (_a = this._outcomes[key], (_a !== null && _a !== void 0 ? _a : 0)) + 1;
|
|
5182
5109
|
}
|
|
@@ -5195,9 +5122,9 @@ var Sentry = (function (exports) {
|
|
|
5195
5122
|
return;
|
|
5196
5123
|
}
|
|
5197
5124
|
logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
|
|
5198
|
-
const url = this._api.
|
|
5125
|
+
const url = getEnvelopeEndpointWithUrlEncodedAuth(this._api.dsn, this._api.tunnel);
|
|
5199
5126
|
// Envelope header is required to be at least an empty object
|
|
5200
|
-
const envelopeHeader = JSON.stringify(Object.assign({}, (this.
|
|
5127
|
+
const envelopeHeader = JSON.stringify(Object.assign({}, (this._api.tunnel && { dsn: dsnToString(this._api.dsn) })));
|
|
5201
5128
|
const itemHeaders = JSON.stringify({
|
|
5202
5129
|
type: 'client_report',
|
|
5203
5130
|
});
|
|
@@ -5224,15 +5151,16 @@ var Sentry = (function (exports) {
|
|
|
5224
5151
|
* Handle Sentry repsonse for promise-based transports.
|
|
5225
5152
|
*/
|
|
5226
5153
|
_handleResponse({ requestType, response, headers, resolve, reject, }) {
|
|
5227
|
-
const status =
|
|
5154
|
+
const status = eventStatusFromHttpCode(response.status);
|
|
5228
5155
|
/**
|
|
5229
5156
|
* "The name is case-insensitive."
|
|
5230
5157
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
|
|
5231
5158
|
*/
|
|
5232
5159
|
const limited = this._handleRateLimit(headers);
|
|
5233
|
-
if (limited)
|
|
5160
|
+
if (limited && isDebugBuild()) {
|
|
5234
5161
|
logger.warn(`Too many ${requestType} requests, backing off until: ${this._disabledUntil(requestType)}`);
|
|
5235
|
-
|
|
5162
|
+
}
|
|
5163
|
+
if (status === 'success') {
|
|
5236
5164
|
resolve({ status });
|
|
5237
5165
|
return;
|
|
5238
5166
|
}
|
|
@@ -5242,7 +5170,7 @@ var Sentry = (function (exports) {
|
|
|
5242
5170
|
* Gets the time that given category is disabled until for rate limiting
|
|
5243
5171
|
*/
|
|
5244
5172
|
_disabledUntil(requestType) {
|
|
5245
|
-
const category =
|
|
5173
|
+
const category = requestTypeToCategory(requestType);
|
|
5246
5174
|
return this._rateLimits[category] || this._rateLimits.all;
|
|
5247
5175
|
}
|
|
5248
5176
|
/**
|
|
@@ -5293,25 +5221,13 @@ var Sentry = (function (exports) {
|
|
|
5293
5221
|
super(options);
|
|
5294
5222
|
this._fetch = fetchImpl;
|
|
5295
5223
|
}
|
|
5296
|
-
/**
|
|
5297
|
-
* @inheritDoc
|
|
5298
|
-
*/
|
|
5299
|
-
sendEvent(event) {
|
|
5300
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5301
|
-
}
|
|
5302
|
-
/**
|
|
5303
|
-
* @inheritDoc
|
|
5304
|
-
*/
|
|
5305
|
-
sendSession(session) {
|
|
5306
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5307
|
-
}
|
|
5308
5224
|
/**
|
|
5309
5225
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5310
5226
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5311
5227
|
*/
|
|
5312
5228
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5313
5229
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5314
|
-
this.recordLostEvent(
|
|
5230
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5315
5231
|
return Promise.reject({
|
|
5316
5232
|
event: originalPayload,
|
|
5317
5233
|
type: sentryRequest.type,
|
|
@@ -5322,9 +5238,9 @@ var Sentry = (function (exports) {
|
|
|
5322
5238
|
const options = {
|
|
5323
5239
|
body: sentryRequest.body,
|
|
5324
5240
|
method: 'POST',
|
|
5325
|
-
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
|
5326
|
-
// https://caniuse.com/#feat=referrer-policy
|
|
5327
|
-
//
|
|
5241
|
+
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
|
|
5242
|
+
// (see https://caniuse.com/#feat=referrer-policy),
|
|
5243
|
+
// it doesn't. And it throws an exception instead of ignoring this parameter...
|
|
5328
5244
|
// REF: https://github.com/getsentry/raven-js/issues/1233
|
|
5329
5245
|
referrerPolicy: (supportsReferrerPolicy() ? 'origin' : ''),
|
|
5330
5246
|
};
|
|
@@ -5355,10 +5271,10 @@ var Sentry = (function (exports) {
|
|
|
5355
5271
|
.then(undefined, reason => {
|
|
5356
5272
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5357
5273
|
if (reason instanceof SentryError) {
|
|
5358
|
-
this.recordLostEvent(
|
|
5274
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5359
5275
|
}
|
|
5360
5276
|
else {
|
|
5361
|
-
this.recordLostEvent(
|
|
5277
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5362
5278
|
}
|
|
5363
5279
|
throw reason;
|
|
5364
5280
|
});
|
|
@@ -5367,25 +5283,13 @@ var Sentry = (function (exports) {
|
|
|
5367
5283
|
|
|
5368
5284
|
/** `XHR` based transport */
|
|
5369
5285
|
class XHRTransport extends BaseTransport {
|
|
5370
|
-
/**
|
|
5371
|
-
* @inheritDoc
|
|
5372
|
-
*/
|
|
5373
|
-
sendEvent(event) {
|
|
5374
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5375
|
-
}
|
|
5376
|
-
/**
|
|
5377
|
-
* @inheritDoc
|
|
5378
|
-
*/
|
|
5379
|
-
sendSession(session) {
|
|
5380
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5381
|
-
}
|
|
5382
5286
|
/**
|
|
5383
5287
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5384
5288
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5385
5289
|
*/
|
|
5386
5290
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5387
5291
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5388
|
-
this.recordLostEvent(
|
|
5292
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5389
5293
|
return Promise.reject({
|
|
5390
5294
|
event: originalPayload,
|
|
5391
5295
|
type: sentryRequest.type,
|
|
@@ -5416,10 +5320,10 @@ var Sentry = (function (exports) {
|
|
|
5416
5320
|
.then(undefined, reason => {
|
|
5417
5321
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5418
5322
|
if (reason instanceof SentryError) {
|
|
5419
|
-
this.recordLostEvent(
|
|
5323
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5420
5324
|
}
|
|
5421
5325
|
else {
|
|
5422
|
-
this.recordLostEvent(
|
|
5326
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5423
5327
|
}
|
|
5424
5328
|
throw reason;
|
|
5425
5329
|
});
|
|
@@ -5498,18 +5402,26 @@ var Sentry = (function (exports) {
|
|
|
5498
5402
|
* @hidden
|
|
5499
5403
|
*/
|
|
5500
5404
|
function wrap(fn, options = {}, before) {
|
|
5405
|
+
// for future readers what this does is wrap a function and then create
|
|
5406
|
+
// a bi-directional wrapping between them.
|
|
5407
|
+
//
|
|
5408
|
+
// example: wrapped = wrap(original);
|
|
5409
|
+
// original.__sentry_wrapped__ -> wrapped
|
|
5410
|
+
// wrapped.__sentry_original__ -> original
|
|
5501
5411
|
if (typeof fn !== 'function') {
|
|
5502
5412
|
return fn;
|
|
5503
5413
|
}
|
|
5504
5414
|
try {
|
|
5415
|
+
// if we're dealing with a function that was previously wrapped, return
|
|
5416
|
+
// the original wrapper.
|
|
5417
|
+
const wrapper = fn.__sentry_wrapped__;
|
|
5418
|
+
if (wrapper) {
|
|
5419
|
+
return wrapper;
|
|
5420
|
+
}
|
|
5505
5421
|
// We don't wanna wrap it twice
|
|
5506
|
-
if (fn
|
|
5422
|
+
if (getOriginalFunction(fn)) {
|
|
5507
5423
|
return fn;
|
|
5508
5424
|
}
|
|
5509
|
-
// If this has already been wrapped in the past, return that wrapped function
|
|
5510
|
-
if (fn.__sentry_wrapped__) {
|
|
5511
|
-
return fn.__sentry_wrapped__;
|
|
5512
|
-
}
|
|
5513
5425
|
}
|
|
5514
5426
|
catch (e) {
|
|
5515
5427
|
// Just accessing custom props in some Selenium environments
|
|
@@ -5527,14 +5439,6 @@ var Sentry = (function (exports) {
|
|
|
5527
5439
|
}
|
|
5528
5440
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
5529
5441
|
const wrappedArguments = args.map((arg) => wrap(arg, options));
|
|
5530
|
-
if (fn.handleEvent) {
|
|
5531
|
-
// Attempt to invoke user-land function
|
|
5532
|
-
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5533
|
-
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
5534
|
-
// is expected behavior and NOT indicative of a bug with sentry.javascript.
|
|
5535
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5536
|
-
return fn.handleEvent.apply(this, wrappedArguments);
|
|
5537
|
-
}
|
|
5538
5442
|
// Attempt to invoke user-land function
|
|
5539
5443
|
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5540
5444
|
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
@@ -5545,13 +5449,12 @@ var Sentry = (function (exports) {
|
|
|
5545
5449
|
ignoreNextOnError();
|
|
5546
5450
|
withScope((scope) => {
|
|
5547
5451
|
scope.addEventProcessor((event) => {
|
|
5548
|
-
const processedEvent = Object.assign({}, event);
|
|
5549
5452
|
if (options.mechanism) {
|
|
5550
|
-
addExceptionTypeValue(
|
|
5551
|
-
addExceptionMechanism(
|
|
5453
|
+
addExceptionTypeValue(event, undefined, undefined);
|
|
5454
|
+
addExceptionMechanism(event, options.mechanism);
|
|
5552
5455
|
}
|
|
5553
|
-
|
|
5554
|
-
return
|
|
5456
|
+
event.extra = Object.assign(Object.assign({}, event.extra), { arguments: args });
|
|
5457
|
+
return event;
|
|
5555
5458
|
});
|
|
5556
5459
|
captureException(ex);
|
|
5557
5460
|
});
|
|
@@ -5569,24 +5472,10 @@ var Sentry = (function (exports) {
|
|
|
5569
5472
|
}
|
|
5570
5473
|
}
|
|
5571
5474
|
catch (_oO) { } // eslint-disable-line no-empty
|
|
5572
|
-
fn.prototype = fn.prototype || {};
|
|
5573
|
-
sentryWrapped.prototype = fn.prototype;
|
|
5574
|
-
Object.defineProperty(fn, '__sentry_wrapped__', {
|
|
5575
|
-
enumerable: false,
|
|
5576
|
-
value: sentryWrapped,
|
|
5577
|
-
});
|
|
5578
5475
|
// Signal that this function has been wrapped/filled already
|
|
5579
5476
|
// for both debugging and to prevent it to being wrapped/filled twice
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
enumerable: false,
|
|
5583
|
-
value: true,
|
|
5584
|
-
},
|
|
5585
|
-
__sentry_original__: {
|
|
5586
|
-
enumerable: false,
|
|
5587
|
-
value: fn,
|
|
5588
|
-
},
|
|
5589
|
-
});
|
|
5477
|
+
markFunctionWrapped(sentryWrapped, fn);
|
|
5478
|
+
addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);
|
|
5590
5479
|
// Restore original function name (not all browsers allow that)
|
|
5591
5480
|
try {
|
|
5592
5481
|
const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name');
|
|
@@ -5611,16 +5500,20 @@ var Sentry = (function (exports) {
|
|
|
5611
5500
|
return;
|
|
5612
5501
|
}
|
|
5613
5502
|
if (!options.eventId) {
|
|
5614
|
-
|
|
5503
|
+
if (isDebugBuild()) {
|
|
5504
|
+
logger.error(`Missing eventId option in showReportDialog call`);
|
|
5505
|
+
}
|
|
5615
5506
|
return;
|
|
5616
5507
|
}
|
|
5617
5508
|
if (!options.dsn) {
|
|
5618
|
-
|
|
5509
|
+
if (isDebugBuild()) {
|
|
5510
|
+
logger.error(`Missing dsn option in showReportDialog call`);
|
|
5511
|
+
}
|
|
5619
5512
|
return;
|
|
5620
5513
|
}
|
|
5621
5514
|
const script = global$5.document.createElement('script');
|
|
5622
5515
|
script.async = true;
|
|
5623
|
-
script.src =
|
|
5516
|
+
script.src = getReportDialogEndpoint(options.dsn, options);
|
|
5624
5517
|
if (options.onLoad) {
|
|
5625
5518
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
5626
5519
|
script.onload = options.onLoad;
|
|
@@ -5640,10 +5533,14 @@ var Sentry = (function (exports) {
|
|
|
5640
5533
|
* @inheritDoc
|
|
5641
5534
|
*/
|
|
5642
5535
|
this.name = GlobalHandlers.id;
|
|
5643
|
-
/**
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5536
|
+
/**
|
|
5537
|
+
* Stores references functions to installing handlers. Will set to undefined
|
|
5538
|
+
* after they have been run so that they are not used twice.
|
|
5539
|
+
*/
|
|
5540
|
+
this._installFunc = {
|
|
5541
|
+
onerror: _installGlobalOnErrorHandler,
|
|
5542
|
+
onunhandledrejection: _installGlobalOnUnhandledRejectionHandler,
|
|
5543
|
+
};
|
|
5647
5544
|
this._options = Object.assign({ onerror: true, onunhandledrejection: true }, options);
|
|
5648
5545
|
}
|
|
5649
5546
|
/**
|
|
@@ -5651,176 +5548,182 @@ var Sentry = (function (exports) {
|
|
|
5651
5548
|
*/
|
|
5652
5549
|
setupOnce() {
|
|
5653
5550
|
Error.stackTraceLimit = 50;
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5551
|
+
const options = this._options;
|
|
5552
|
+
// We can disable guard-for-in as we construct the options object above + do checks against
|
|
5553
|
+
// `this._installFunc` for the property.
|
|
5554
|
+
// eslint-disable-next-line guard-for-in
|
|
5555
|
+
for (const key in options) {
|
|
5556
|
+
const installFunc = this._installFunc[key];
|
|
5557
|
+
if (installFunc && options[key]) {
|
|
5558
|
+
globalHandlerLog(key);
|
|
5559
|
+
installFunc();
|
|
5560
|
+
this._installFunc[key] = undefined;
|
|
5561
|
+
}
|
|
5661
5562
|
}
|
|
5662
5563
|
}
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5564
|
+
}
|
|
5565
|
+
/**
|
|
5566
|
+
* @inheritDoc
|
|
5567
|
+
*/
|
|
5568
|
+
GlobalHandlers.id = 'GlobalHandlers';
|
|
5569
|
+
/** JSDoc */
|
|
5570
|
+
function _installGlobalOnErrorHandler() {
|
|
5571
|
+
addInstrumentationHandler('error',
|
|
5572
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5573
|
+
(data) => {
|
|
5574
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5575
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5666
5576
|
return;
|
|
5667
5577
|
}
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
callback: (data) => {
|
|
5671
|
-
const error = data.error;
|
|
5672
|
-
const currentHub = getCurrentHub();
|
|
5673
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5674
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5675
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5676
|
-
return;
|
|
5677
|
-
}
|
|
5678
|
-
const client = currentHub.getClient();
|
|
5679
|
-
const event = error === undefined && isString(data.msg)
|
|
5680
|
-
? this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
|
|
5681
|
-
: this._enhanceEventWithInitialFrame(eventFromUnknownInput(error || data.msg, undefined, {
|
|
5682
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5683
|
-
rejection: false,
|
|
5684
|
-
}), data.url, data.line, data.column);
|
|
5685
|
-
addExceptionMechanism(event, {
|
|
5686
|
-
handled: false,
|
|
5687
|
-
type: 'onerror',
|
|
5688
|
-
});
|
|
5689
|
-
currentHub.captureEvent(event, {
|
|
5690
|
-
originalException: error,
|
|
5691
|
-
});
|
|
5692
|
-
},
|
|
5693
|
-
type: 'error',
|
|
5694
|
-
});
|
|
5695
|
-
this._onErrorHandlerInstalled = true;
|
|
5696
|
-
}
|
|
5697
|
-
/** JSDoc */
|
|
5698
|
-
_installGlobalOnUnhandledRejectionHandler() {
|
|
5699
|
-
if (this._onUnhandledRejectionHandlerInstalled) {
|
|
5578
|
+
const { msg, url, line, column, error } = data;
|
|
5579
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5700
5580
|
return;
|
|
5701
5581
|
}
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5715
|
-
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5716
|
-
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5717
|
-
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5718
|
-
else if ('detail' in e && 'reason' in e.detail) {
|
|
5719
|
-
error = e.detail.reason;
|
|
5720
|
-
}
|
|
5721
|
-
}
|
|
5722
|
-
catch (_oO) {
|
|
5723
|
-
// no-empty
|
|
5724
|
-
}
|
|
5725
|
-
const currentHub = getCurrentHub();
|
|
5726
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5727
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5728
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5729
|
-
return true;
|
|
5730
|
-
}
|
|
5731
|
-
const client = currentHub.getClient();
|
|
5732
|
-
const event = isPrimitive(error)
|
|
5733
|
-
? this._eventFromRejectionWithPrimitive(error)
|
|
5734
|
-
: eventFromUnknownInput(error, undefined, {
|
|
5735
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5736
|
-
rejection: true,
|
|
5737
|
-
});
|
|
5738
|
-
event.level = exports.Severity.Error;
|
|
5739
|
-
addExceptionMechanism(event, {
|
|
5740
|
-
handled: false,
|
|
5741
|
-
type: 'onunhandledrejection',
|
|
5742
|
-
});
|
|
5743
|
-
currentHub.captureEvent(event, {
|
|
5744
|
-
originalException: error,
|
|
5745
|
-
});
|
|
5746
|
-
return;
|
|
5747
|
-
},
|
|
5748
|
-
type: 'unhandledrejection',
|
|
5749
|
-
});
|
|
5750
|
-
this._onUnhandledRejectionHandlerInstalled = true;
|
|
5751
|
-
}
|
|
5752
|
-
/**
|
|
5753
|
-
* This function creates a stack from an old, error-less onerror handler.
|
|
5754
|
-
*/
|
|
5755
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5756
|
-
_eventFromIncompleteOnError(msg, url, line, column) {
|
|
5757
|
-
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5758
|
-
// If 'message' is ErrorEvent, get real message from inside
|
|
5759
|
-
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5760
|
-
let name;
|
|
5761
|
-
const groups = message.match(ERROR_TYPES_RE);
|
|
5762
|
-
if (groups) {
|
|
5763
|
-
name = groups[1];
|
|
5764
|
-
message = groups[2];
|
|
5765
|
-
}
|
|
5766
|
-
const event = {
|
|
5767
|
-
exception: {
|
|
5768
|
-
values: [
|
|
5769
|
-
{
|
|
5770
|
-
type: name || 'Error',
|
|
5771
|
-
value: message,
|
|
5772
|
-
},
|
|
5773
|
-
],
|
|
5774
|
-
},
|
|
5775
|
-
};
|
|
5776
|
-
return this._enhanceEventWithInitialFrame(event, url, line, column);
|
|
5777
|
-
}
|
|
5778
|
-
/**
|
|
5779
|
-
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5780
|
-
*
|
|
5781
|
-
* @param reason: The `reason` property of the promise rejection
|
|
5782
|
-
* @returns An Event object with an appropriate `exception` value
|
|
5783
|
-
*/
|
|
5784
|
-
_eventFromRejectionWithPrimitive(reason) {
|
|
5785
|
-
return {
|
|
5786
|
-
exception: {
|
|
5787
|
-
values: [
|
|
5788
|
-
{
|
|
5789
|
-
type: 'UnhandledRejection',
|
|
5790
|
-
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5791
|
-
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5792
|
-
},
|
|
5793
|
-
],
|
|
5794
|
-
},
|
|
5795
|
-
};
|
|
5796
|
-
}
|
|
5797
|
-
/** JSDoc */
|
|
5582
|
+
const event = error === undefined && isString(msg)
|
|
5583
|
+
? _eventFromIncompleteOnError(msg, url, line, column)
|
|
5584
|
+
: _enhanceEventWithInitialFrame(eventFromUnknownInput(error || msg, undefined, {
|
|
5585
|
+
attachStacktrace,
|
|
5586
|
+
isRejection: false,
|
|
5587
|
+
}), url, line, column);
|
|
5588
|
+
addMechanismAndCapture(hub, error, event, 'onerror');
|
|
5589
|
+
});
|
|
5590
|
+
}
|
|
5591
|
+
/** JSDoc */
|
|
5592
|
+
function _installGlobalOnUnhandledRejectionHandler() {
|
|
5593
|
+
addInstrumentationHandler('unhandledrejection',
|
|
5798
5594
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {};
|
|
5804
|
-
event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || [];
|
|
5805
|
-
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5806
|
-
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5807
|
-
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5808
|
-
if (event.exception.values[0].stacktrace.frames.length === 0) {
|
|
5809
|
-
event.exception.values[0].stacktrace.frames.push({
|
|
5810
|
-
colno,
|
|
5811
|
-
filename,
|
|
5812
|
-
function: '?',
|
|
5813
|
-
in_app: true,
|
|
5814
|
-
lineno,
|
|
5815
|
-
});
|
|
5595
|
+
(e) => {
|
|
5596
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5597
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5598
|
+
return;
|
|
5816
5599
|
}
|
|
5817
|
-
|
|
5818
|
-
|
|
5600
|
+
let error = e;
|
|
5601
|
+
// dig the object of the rejection out of known event types
|
|
5602
|
+
try {
|
|
5603
|
+
// PromiseRejectionEvents store the object of the rejection under 'reason'
|
|
5604
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
|
|
5605
|
+
if ('reason' in e) {
|
|
5606
|
+
error = e.reason;
|
|
5607
|
+
}
|
|
5608
|
+
// something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
|
|
5609
|
+
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5610
|
+
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5611
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5612
|
+
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5613
|
+
else if ('detail' in e && 'reason' in e.detail) {
|
|
5614
|
+
error = e.detail.reason;
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
catch (_oO) {
|
|
5618
|
+
// no-empty
|
|
5619
|
+
}
|
|
5620
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5621
|
+
return true;
|
|
5622
|
+
}
|
|
5623
|
+
const event = isPrimitive(error)
|
|
5624
|
+
? _eventFromRejectionWithPrimitive(error)
|
|
5625
|
+
: eventFromUnknownInput(error, undefined, {
|
|
5626
|
+
attachStacktrace,
|
|
5627
|
+
isRejection: true,
|
|
5628
|
+
});
|
|
5629
|
+
event.level = exports.Severity.Error;
|
|
5630
|
+
addMechanismAndCapture(hub, error, event, 'onunhandledrejection');
|
|
5631
|
+
return;
|
|
5632
|
+
});
|
|
5819
5633
|
}
|
|
5820
5634
|
/**
|
|
5821
|
-
*
|
|
5635
|
+
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5636
|
+
*
|
|
5637
|
+
* @param reason: The `reason` property of the promise rejection
|
|
5638
|
+
* @returns An Event object with an appropriate `exception` value
|
|
5639
|
+
*/
|
|
5640
|
+
function _eventFromRejectionWithPrimitive(reason) {
|
|
5641
|
+
return {
|
|
5642
|
+
exception: {
|
|
5643
|
+
values: [
|
|
5644
|
+
{
|
|
5645
|
+
type: 'UnhandledRejection',
|
|
5646
|
+
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5647
|
+
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5648
|
+
},
|
|
5649
|
+
],
|
|
5650
|
+
},
|
|
5651
|
+
};
|
|
5652
|
+
}
|
|
5653
|
+
/**
|
|
5654
|
+
* This function creates a stack from an old, error-less onerror handler.
|
|
5822
5655
|
*/
|
|
5823
|
-
|
|
5656
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5657
|
+
function _eventFromIncompleteOnError(msg, url, line, column) {
|
|
5658
|
+
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5659
|
+
// If 'message' is ErrorEvent, get real message from inside
|
|
5660
|
+
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5661
|
+
let name = 'Error';
|
|
5662
|
+
const groups = message.match(ERROR_TYPES_RE);
|
|
5663
|
+
if (groups) {
|
|
5664
|
+
name = groups[1];
|
|
5665
|
+
message = groups[2];
|
|
5666
|
+
}
|
|
5667
|
+
const event = {
|
|
5668
|
+
exception: {
|
|
5669
|
+
values: [
|
|
5670
|
+
{
|
|
5671
|
+
type: name,
|
|
5672
|
+
value: message,
|
|
5673
|
+
},
|
|
5674
|
+
],
|
|
5675
|
+
},
|
|
5676
|
+
};
|
|
5677
|
+
return _enhanceEventWithInitialFrame(event, url, line, column);
|
|
5678
|
+
}
|
|
5679
|
+
/** JSDoc */
|
|
5680
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5681
|
+
function _enhanceEventWithInitialFrame(event, url, line, column) {
|
|
5682
|
+
// event.exception
|
|
5683
|
+
const e = (event.exception = event.exception || {});
|
|
5684
|
+
// event.exception.values
|
|
5685
|
+
const ev = (e.values = e.values || []);
|
|
5686
|
+
// event.exception.values[0]
|
|
5687
|
+
const ev0 = (ev[0] = ev[0] || {});
|
|
5688
|
+
// event.exception.values[0].stacktrace
|
|
5689
|
+
const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
|
|
5690
|
+
// event.exception.values[0].stacktrace.frames
|
|
5691
|
+
const ev0sf = (ev0s.frames = ev0s.frames || []);
|
|
5692
|
+
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5693
|
+
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5694
|
+
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5695
|
+
// event.exception.values[0].stacktrace.frames
|
|
5696
|
+
if (ev0sf.length === 0) {
|
|
5697
|
+
ev0sf.push({
|
|
5698
|
+
colno,
|
|
5699
|
+
filename,
|
|
5700
|
+
function: '?',
|
|
5701
|
+
in_app: true,
|
|
5702
|
+
lineno,
|
|
5703
|
+
});
|
|
5704
|
+
}
|
|
5705
|
+
return event;
|
|
5706
|
+
}
|
|
5707
|
+
function globalHandlerLog(type) {
|
|
5708
|
+
if (isDebugBuild()) {
|
|
5709
|
+
logger.log(`Global Handler attached: ${type}`);
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5712
|
+
function addMechanismAndCapture(hub, error, event, type) {
|
|
5713
|
+
addExceptionMechanism(event, {
|
|
5714
|
+
handled: false,
|
|
5715
|
+
type,
|
|
5716
|
+
});
|
|
5717
|
+
hub.captureEvent(event, {
|
|
5718
|
+
originalException: error,
|
|
5719
|
+
});
|
|
5720
|
+
}
|
|
5721
|
+
function getHubAndAttachStacktrace() {
|
|
5722
|
+
const hub = getCurrentHub();
|
|
5723
|
+
const client = hub.getClient();
|
|
5724
|
+
const attachStacktrace = client && client.getOptions().attachStacktrace;
|
|
5725
|
+
return [hub, attachStacktrace];
|
|
5726
|
+
}
|
|
5824
5727
|
|
|
5825
5728
|
const DEFAULT_EVENT_TARGET = [
|
|
5826
5729
|
'EventTarget',
|
|
@@ -5872,172 +5775,173 @@ var Sentry = (function (exports) {
|
|
|
5872
5775
|
setupOnce() {
|
|
5873
5776
|
const global = getGlobalObject();
|
|
5874
5777
|
if (this._options.setTimeout) {
|
|
5875
|
-
fill(global, 'setTimeout',
|
|
5778
|
+
fill(global, 'setTimeout', _wrapTimeFunction);
|
|
5876
5779
|
}
|
|
5877
5780
|
if (this._options.setInterval) {
|
|
5878
|
-
fill(global, 'setInterval',
|
|
5781
|
+
fill(global, 'setInterval', _wrapTimeFunction);
|
|
5879
5782
|
}
|
|
5880
5783
|
if (this._options.requestAnimationFrame) {
|
|
5881
|
-
fill(global, 'requestAnimationFrame',
|
|
5784
|
+
fill(global, 'requestAnimationFrame', _wrapRAF);
|
|
5882
5785
|
}
|
|
5883
5786
|
if (this._options.XMLHttpRequest && 'XMLHttpRequest' in global) {
|
|
5884
|
-
fill(XMLHttpRequest.prototype, 'send',
|
|
5787
|
+
fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
|
|
5885
5788
|
}
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
eventTarget.
|
|
5789
|
+
const eventTargetOption = this._options.eventTarget;
|
|
5790
|
+
if (eventTargetOption) {
|
|
5791
|
+
const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
|
|
5792
|
+
eventTarget.forEach(_wrapEventTarget);
|
|
5889
5793
|
}
|
|
5890
5794
|
}
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
data: { function: getFunctionName(original) },
|
|
5899
|
-
handled: true,
|
|
5900
|
-
type: 'instrument',
|
|
5901
|
-
},
|
|
5902
|
-
});
|
|
5903
|
-
return original.apply(this, args);
|
|
5904
|
-
};
|
|
5905
|
-
}
|
|
5906
|
-
/** JSDoc */
|
|
5795
|
+
}
|
|
5796
|
+
/**
|
|
5797
|
+
* @inheritDoc
|
|
5798
|
+
*/
|
|
5799
|
+
TryCatch.id = 'TryCatch';
|
|
5800
|
+
/** JSDoc */
|
|
5801
|
+
function _wrapTimeFunction(original) {
|
|
5907
5802
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5803
|
+
return function (...args) {
|
|
5804
|
+
const originalCallback = args[0];
|
|
5805
|
+
args[0] = wrap(originalCallback, {
|
|
5806
|
+
mechanism: {
|
|
5807
|
+
data: { function: getFunctionName(original) },
|
|
5808
|
+
handled: true,
|
|
5809
|
+
type: 'instrument',
|
|
5810
|
+
},
|
|
5811
|
+
});
|
|
5812
|
+
return original.apply(this, args);
|
|
5813
|
+
};
|
|
5814
|
+
}
|
|
5815
|
+
/** JSDoc */
|
|
5816
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5817
|
+
function _wrapRAF(original) {
|
|
5818
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5819
|
+
return function (callback) {
|
|
5820
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5821
|
+
return original.call(this, wrap(callback, {
|
|
5822
|
+
mechanism: {
|
|
5823
|
+
data: {
|
|
5824
|
+
function: 'requestAnimationFrame',
|
|
5825
|
+
handler: getFunctionName(original),
|
|
5920
5826
|
},
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
try {
|
|
5937
|
-
if (typeof fn.handleEvent === 'function') {
|
|
5938
|
-
fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
|
|
5939
|
-
mechanism: {
|
|
5940
|
-
data: {
|
|
5941
|
-
function: 'handleEvent',
|
|
5942
|
-
handler: getFunctionName(fn),
|
|
5943
|
-
target,
|
|
5944
|
-
},
|
|
5945
|
-
handled: true,
|
|
5946
|
-
type: 'instrument',
|
|
5947
|
-
},
|
|
5948
|
-
});
|
|
5949
|
-
}
|
|
5950
|
-
}
|
|
5951
|
-
catch (err) {
|
|
5952
|
-
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5953
|
-
}
|
|
5954
|
-
return original.call(this, eventName,
|
|
5827
|
+
handled: true,
|
|
5828
|
+
type: 'instrument',
|
|
5829
|
+
},
|
|
5830
|
+
}));
|
|
5831
|
+
};
|
|
5832
|
+
}
|
|
5833
|
+
/** JSDoc */
|
|
5834
|
+
function _wrapXHR(originalSend) {
|
|
5835
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5836
|
+
return function (...args) {
|
|
5837
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
5838
|
+
const xhr = this;
|
|
5839
|
+
const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
|
|
5840
|
+
xmlHttpRequestProps.forEach(prop => {
|
|
5841
|
+
if (prop in xhr && typeof xhr[prop] === 'function') {
|
|
5955
5842
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5843
|
+
fill(xhr, prop, function (original) {
|
|
5844
|
+
const wrapOptions = {
|
|
5845
|
+
mechanism: {
|
|
5846
|
+
data: {
|
|
5847
|
+
function: prop,
|
|
5848
|
+
handler: getFunctionName(original),
|
|
5849
|
+
},
|
|
5850
|
+
handled: true,
|
|
5851
|
+
type: 'instrument',
|
|
5962
5852
|
},
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
});
|
|
5969
|
-
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5970
|
-
return function (eventName, fn, options) {
|
|
5971
|
-
var _a;
|
|
5972
|
-
/**
|
|
5973
|
-
* There are 2 possible scenarios here:
|
|
5974
|
-
*
|
|
5975
|
-
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5976
|
-
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5977
|
-
* as a pass-through, and call original `removeEventListener` with it.
|
|
5978
|
-
*
|
|
5979
|
-
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5980
|
-
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5981
|
-
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5982
|
-
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5983
|
-
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5984
|
-
*
|
|
5985
|
-
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5986
|
-
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5987
|
-
* to get rid of the initial handler and it'd stick there forever.
|
|
5988
|
-
*/
|
|
5989
|
-
const wrappedEventHandler = fn;
|
|
5990
|
-
try {
|
|
5991
|
-
const originalEventHandler = (_a = wrappedEventHandler) === null || _a === void 0 ? void 0 : _a.__sentry_wrapped__;
|
|
5992
|
-
if (originalEventHandler) {
|
|
5993
|
-
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5853
|
+
};
|
|
5854
|
+
// If Instrument integration has been called before TryCatch, get the name of original function
|
|
5855
|
+
const originalFunction = getOriginalFunction(original);
|
|
5856
|
+
if (originalFunction) {
|
|
5857
|
+
wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);
|
|
5994
5858
|
}
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
6000
|
-
};
|
|
5859
|
+
// Otherwise wrap directly
|
|
5860
|
+
return wrap(original, wrapOptions);
|
|
5861
|
+
});
|
|
5862
|
+
}
|
|
6001
5863
|
});
|
|
5864
|
+
return originalSend.apply(this, args);
|
|
5865
|
+
};
|
|
5866
|
+
}
|
|
5867
|
+
/** JSDoc */
|
|
5868
|
+
function _wrapEventTarget(target) {
|
|
5869
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5870
|
+
const global = getGlobalObject();
|
|
5871
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5872
|
+
const proto = global[target] && global[target].prototype;
|
|
5873
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
|
|
5874
|
+
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
|
|
5875
|
+
return;
|
|
6002
5876
|
}
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
fill(xhr, prop, function (original) {
|
|
6014
|
-
const wrapOptions = {
|
|
6015
|
-
mechanism: {
|
|
6016
|
-
data: {
|
|
6017
|
-
function: prop,
|
|
6018
|
-
handler: getFunctionName(original),
|
|
6019
|
-
},
|
|
6020
|
-
handled: true,
|
|
6021
|
-
type: 'instrument',
|
|
5877
|
+
fill(proto, 'addEventListener', function (original) {
|
|
5878
|
+
return function (eventName, fn, options) {
|
|
5879
|
+
try {
|
|
5880
|
+
if (typeof fn.handleEvent === 'function') {
|
|
5881
|
+
fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
|
|
5882
|
+
mechanism: {
|
|
5883
|
+
data: {
|
|
5884
|
+
function: 'handleEvent',
|
|
5885
|
+
handler: getFunctionName(fn),
|
|
5886
|
+
target,
|
|
6022
5887
|
},
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
wrapOptions.mechanism.data.handler = getFunctionName(original.__sentry_original__);
|
|
6027
|
-
}
|
|
6028
|
-
// Otherwise wrap directly
|
|
6029
|
-
return wrap(original, wrapOptions);
|
|
5888
|
+
handled: true,
|
|
5889
|
+
type: 'instrument',
|
|
5890
|
+
},
|
|
6030
5891
|
});
|
|
6031
5892
|
}
|
|
6032
|
-
}
|
|
6033
|
-
|
|
5893
|
+
}
|
|
5894
|
+
catch (err) {
|
|
5895
|
+
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5896
|
+
}
|
|
5897
|
+
return original.call(this, eventName,
|
|
5898
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5899
|
+
wrap(fn, {
|
|
5900
|
+
mechanism: {
|
|
5901
|
+
data: {
|
|
5902
|
+
function: 'addEventListener',
|
|
5903
|
+
handler: getFunctionName(fn),
|
|
5904
|
+
target,
|
|
5905
|
+
},
|
|
5906
|
+
handled: true,
|
|
5907
|
+
type: 'instrument',
|
|
5908
|
+
},
|
|
5909
|
+
}), options);
|
|
6034
5910
|
};
|
|
6035
|
-
}
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
5911
|
+
});
|
|
5912
|
+
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5913
|
+
return function (eventName, fn, options) {
|
|
5914
|
+
/**
|
|
5915
|
+
* There are 2 possible scenarios here:
|
|
5916
|
+
*
|
|
5917
|
+
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5918
|
+
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5919
|
+
* as a pass-through, and call original `removeEventListener` with it.
|
|
5920
|
+
*
|
|
5921
|
+
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5922
|
+
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5923
|
+
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5924
|
+
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5925
|
+
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5926
|
+
*
|
|
5927
|
+
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5928
|
+
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5929
|
+
* to get rid of the initial handler and it'd stick there forever.
|
|
5930
|
+
*/
|
|
5931
|
+
const wrappedEventHandler = fn;
|
|
5932
|
+
try {
|
|
5933
|
+
const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
|
|
5934
|
+
if (originalEventHandler) {
|
|
5935
|
+
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5936
|
+
}
|
|
5937
|
+
}
|
|
5938
|
+
catch (e) {
|
|
5939
|
+
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
|
|
5940
|
+
}
|
|
5941
|
+
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
5942
|
+
};
|
|
5943
|
+
});
|
|
5944
|
+
}
|
|
6041
5945
|
|
|
6042
5946
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
6043
5947
|
/**
|
|
@@ -6081,82 +5985,36 @@ var Sentry = (function (exports) {
|
|
|
6081
5985
|
*/
|
|
6082
5986
|
setupOnce() {
|
|
6083
5987
|
if (this._options.console) {
|
|
6084
|
-
addInstrumentationHandler(
|
|
6085
|
-
callback: (...args) => {
|
|
6086
|
-
this._consoleBreadcrumb(...args);
|
|
6087
|
-
},
|
|
6088
|
-
type: 'console',
|
|
6089
|
-
});
|
|
5988
|
+
addInstrumentationHandler('console', _consoleBreadcrumb);
|
|
6090
5989
|
}
|
|
6091
5990
|
if (this._options.dom) {
|
|
6092
|
-
addInstrumentationHandler(
|
|
6093
|
-
callback: (...args) => {
|
|
6094
|
-
this._domBreadcrumb(...args);
|
|
6095
|
-
},
|
|
6096
|
-
type: 'dom',
|
|
6097
|
-
});
|
|
5991
|
+
addInstrumentationHandler('dom', _domBreadcrumb(this._options.dom));
|
|
6098
5992
|
}
|
|
6099
5993
|
if (this._options.xhr) {
|
|
6100
|
-
addInstrumentationHandler(
|
|
6101
|
-
callback: (...args) => {
|
|
6102
|
-
this._xhrBreadcrumb(...args);
|
|
6103
|
-
},
|
|
6104
|
-
type: 'xhr',
|
|
6105
|
-
});
|
|
5994
|
+
addInstrumentationHandler('xhr', _xhrBreadcrumb);
|
|
6106
5995
|
}
|
|
6107
5996
|
if (this._options.fetch) {
|
|
6108
|
-
addInstrumentationHandler(
|
|
6109
|
-
callback: (...args) => {
|
|
6110
|
-
this._fetchBreadcrumb(...args);
|
|
6111
|
-
},
|
|
6112
|
-
type: 'fetch',
|
|
6113
|
-
});
|
|
5997
|
+
addInstrumentationHandler('fetch', _fetchBreadcrumb);
|
|
6114
5998
|
}
|
|
6115
5999
|
if (this._options.history) {
|
|
6116
|
-
addInstrumentationHandler(
|
|
6117
|
-
callback: (...args) => {
|
|
6118
|
-
this._historyBreadcrumb(...args);
|
|
6119
|
-
},
|
|
6120
|
-
type: 'history',
|
|
6121
|
-
});
|
|
6122
|
-
}
|
|
6123
|
-
}
|
|
6124
|
-
/**
|
|
6125
|
-
* Creates breadcrumbs from console API calls
|
|
6126
|
-
*/
|
|
6127
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6128
|
-
_consoleBreadcrumb(handlerData) {
|
|
6129
|
-
const breadcrumb = {
|
|
6130
|
-
category: 'console',
|
|
6131
|
-
data: {
|
|
6132
|
-
arguments: handlerData.args,
|
|
6133
|
-
logger: 'console',
|
|
6134
|
-
},
|
|
6135
|
-
level: exports.Severity.fromString(handlerData.level),
|
|
6136
|
-
message: safeJoin(handlerData.args, ' '),
|
|
6137
|
-
};
|
|
6138
|
-
if (handlerData.level === 'assert') {
|
|
6139
|
-
if (handlerData.args[0] === false) {
|
|
6140
|
-
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6141
|
-
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6142
|
-
}
|
|
6143
|
-
else {
|
|
6144
|
-
// Don't capture a breadcrumb for passed assertions
|
|
6145
|
-
return;
|
|
6146
|
-
}
|
|
6000
|
+
addInstrumentationHandler('history', _historyBreadcrumb);
|
|
6147
6001
|
}
|
|
6148
|
-
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6149
|
-
input: handlerData.args,
|
|
6150
|
-
level: handlerData.level,
|
|
6151
|
-
});
|
|
6152
6002
|
}
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6003
|
+
}
|
|
6004
|
+
/**
|
|
6005
|
+
* @inheritDoc
|
|
6006
|
+
*/
|
|
6007
|
+
Breadcrumbs.id = 'Breadcrumbs';
|
|
6008
|
+
/**
|
|
6009
|
+
* A HOC that creaes a function that creates breadcrumbs from DOM API calls.
|
|
6010
|
+
* This is a HOC so that we get access to dom options in the closure.
|
|
6011
|
+
*/
|
|
6012
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6013
|
+
function _domBreadcrumb(dom) {
|
|
6156
6014
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6157
|
-
|
|
6015
|
+
function _innerDomBreadcrumb(handlerData) {
|
|
6158
6016
|
let target;
|
|
6159
|
-
let keyAttrs = typeof
|
|
6017
|
+
let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
|
|
6160
6018
|
if (typeof keyAttrs === 'string') {
|
|
6161
6019
|
keyAttrs = [keyAttrs];
|
|
6162
6020
|
}
|
|
@@ -6181,103 +6039,129 @@ var Sentry = (function (exports) {
|
|
|
6181
6039
|
global: handlerData.global,
|
|
6182
6040
|
});
|
|
6183
6041
|
}
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
xhr: handlerData.xhr,
|
|
6205
|
-
input: body,
|
|
6206
|
-
});
|
|
6207
|
-
return;
|
|
6208
|
-
}
|
|
6209
|
-
}
|
|
6210
|
-
/**
|
|
6211
|
-
* Creates breadcrumbs from fetch API calls
|
|
6212
|
-
*/
|
|
6213
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6214
|
-
_fetchBreadcrumb(handlerData) {
|
|
6215
|
-
// We only capture complete fetch requests
|
|
6216
|
-
if (!handlerData.endTimestamp) {
|
|
6217
|
-
return;
|
|
6218
|
-
}
|
|
6219
|
-
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6220
|
-
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6221
|
-
return;
|
|
6222
|
-
}
|
|
6223
|
-
if (handlerData.error) {
|
|
6224
|
-
getCurrentHub().addBreadcrumb({
|
|
6225
|
-
category: 'fetch',
|
|
6226
|
-
data: handlerData.fetchData,
|
|
6227
|
-
level: exports.Severity.Error,
|
|
6228
|
-
type: 'http',
|
|
6229
|
-
}, {
|
|
6230
|
-
data: handlerData.error,
|
|
6231
|
-
input: handlerData.args,
|
|
6232
|
-
});
|
|
6042
|
+
return _innerDomBreadcrumb;
|
|
6043
|
+
}
|
|
6044
|
+
/**
|
|
6045
|
+
* Creates breadcrumbs from console API calls
|
|
6046
|
+
*/
|
|
6047
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6048
|
+
function _consoleBreadcrumb(handlerData) {
|
|
6049
|
+
const breadcrumb = {
|
|
6050
|
+
category: 'console',
|
|
6051
|
+
data: {
|
|
6052
|
+
arguments: handlerData.args,
|
|
6053
|
+
logger: 'console',
|
|
6054
|
+
},
|
|
6055
|
+
level: severityFromString(handlerData.level),
|
|
6056
|
+
message: safeJoin(handlerData.args, ' '),
|
|
6057
|
+
};
|
|
6058
|
+
if (handlerData.level === 'assert') {
|
|
6059
|
+
if (handlerData.args[0] === false) {
|
|
6060
|
+
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6061
|
+
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6233
6062
|
}
|
|
6234
6063
|
else {
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6238
|
-
type: 'http',
|
|
6239
|
-
}, {
|
|
6240
|
-
input: handlerData.args,
|
|
6241
|
-
response: handlerData.response,
|
|
6242
|
-
});
|
|
6064
|
+
// Don't capture a breadcrumb for passed assertions
|
|
6065
|
+
return;
|
|
6243
6066
|
}
|
|
6244
6067
|
}
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
//
|
|
6257
|
-
if (
|
|
6258
|
-
|
|
6259
|
-
}
|
|
6260
|
-
// Use only the path component of the URL if the URL matches the current
|
|
6261
|
-
// document (almost all the time when using pushState)
|
|
6262
|
-
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6263
|
-
to = parsedTo.relative;
|
|
6264
|
-
}
|
|
6265
|
-
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6266
|
-
from = parsedFrom.relative;
|
|
6068
|
+
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6069
|
+
input: handlerData.args,
|
|
6070
|
+
level: handlerData.level,
|
|
6071
|
+
});
|
|
6072
|
+
}
|
|
6073
|
+
/**
|
|
6074
|
+
* Creates breadcrumbs from XHR API calls
|
|
6075
|
+
*/
|
|
6076
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6077
|
+
function _xhrBreadcrumb(handlerData) {
|
|
6078
|
+
if (handlerData.endTimestamp) {
|
|
6079
|
+
// We only capture complete, non-sentry requests
|
|
6080
|
+
if (handlerData.xhr.__sentry_own_request__) {
|
|
6081
|
+
return;
|
|
6267
6082
|
}
|
|
6083
|
+
const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {};
|
|
6268
6084
|
getCurrentHub().addBreadcrumb({
|
|
6269
|
-
category: '
|
|
6085
|
+
category: 'xhr',
|
|
6270
6086
|
data: {
|
|
6271
|
-
|
|
6272
|
-
|
|
6087
|
+
method,
|
|
6088
|
+
url,
|
|
6089
|
+
status_code,
|
|
6273
6090
|
},
|
|
6091
|
+
type: 'http',
|
|
6092
|
+
}, {
|
|
6093
|
+
xhr: handlerData.xhr,
|
|
6094
|
+
input: body,
|
|
6274
6095
|
});
|
|
6096
|
+
return;
|
|
6275
6097
|
}
|
|
6276
6098
|
}
|
|
6277
6099
|
/**
|
|
6278
|
-
*
|
|
6100
|
+
* Creates breadcrumbs from fetch API calls
|
|
6101
|
+
*/
|
|
6102
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6103
|
+
function _fetchBreadcrumb(handlerData) {
|
|
6104
|
+
// We only capture complete fetch requests
|
|
6105
|
+
if (!handlerData.endTimestamp) {
|
|
6106
|
+
return;
|
|
6107
|
+
}
|
|
6108
|
+
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6109
|
+
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6110
|
+
return;
|
|
6111
|
+
}
|
|
6112
|
+
if (handlerData.error) {
|
|
6113
|
+
getCurrentHub().addBreadcrumb({
|
|
6114
|
+
category: 'fetch',
|
|
6115
|
+
data: handlerData.fetchData,
|
|
6116
|
+
level: exports.Severity.Error,
|
|
6117
|
+
type: 'http',
|
|
6118
|
+
}, {
|
|
6119
|
+
data: handlerData.error,
|
|
6120
|
+
input: handlerData.args,
|
|
6121
|
+
});
|
|
6122
|
+
}
|
|
6123
|
+
else {
|
|
6124
|
+
getCurrentHub().addBreadcrumb({
|
|
6125
|
+
category: 'fetch',
|
|
6126
|
+
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6127
|
+
type: 'http',
|
|
6128
|
+
}, {
|
|
6129
|
+
input: handlerData.args,
|
|
6130
|
+
response: handlerData.response,
|
|
6131
|
+
});
|
|
6132
|
+
}
|
|
6133
|
+
}
|
|
6134
|
+
/**
|
|
6135
|
+
* Creates breadcrumbs from history API calls
|
|
6279
6136
|
*/
|
|
6280
|
-
|
|
6137
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6138
|
+
function _historyBreadcrumb(handlerData) {
|
|
6139
|
+
const global = getGlobalObject();
|
|
6140
|
+
let from = handlerData.from;
|
|
6141
|
+
let to = handlerData.to;
|
|
6142
|
+
const parsedLoc = parseUrl(global.location.href);
|
|
6143
|
+
let parsedFrom = parseUrl(from);
|
|
6144
|
+
const parsedTo = parseUrl(to);
|
|
6145
|
+
// Initial pushState doesn't provide `from` information
|
|
6146
|
+
if (!parsedFrom.path) {
|
|
6147
|
+
parsedFrom = parsedLoc;
|
|
6148
|
+
}
|
|
6149
|
+
// Use only the path component of the URL if the URL matches the current
|
|
6150
|
+
// document (almost all the time when using pushState)
|
|
6151
|
+
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6152
|
+
to = parsedTo.relative;
|
|
6153
|
+
}
|
|
6154
|
+
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6155
|
+
from = parsedFrom.relative;
|
|
6156
|
+
}
|
|
6157
|
+
getCurrentHub().addBreadcrumb({
|
|
6158
|
+
category: 'navigation',
|
|
6159
|
+
data: {
|
|
6160
|
+
from,
|
|
6161
|
+
to,
|
|
6162
|
+
},
|
|
6163
|
+
});
|
|
6164
|
+
}
|
|
6281
6165
|
|
|
6282
6166
|
const DEFAULT_KEY = 'cause';
|
|
6283
6167
|
const DEFAULT_LIMIT = 5;
|
|
@@ -6300,40 +6184,36 @@ var Sentry = (function (exports) {
|
|
|
6300
6184
|
setupOnce() {
|
|
6301
6185
|
addGlobalEventProcessor((event, hint) => {
|
|
6302
6186
|
const self = getCurrentHub().getIntegration(LinkedErrors);
|
|
6303
|
-
|
|
6304
|
-
const handler = self._handler && self._handler.bind(self);
|
|
6305
|
-
return typeof handler === 'function' ? handler(event, hint) : event;
|
|
6306
|
-
}
|
|
6307
|
-
return event;
|
|
6187
|
+
return self ? _handler(self._key, self._limit, event, hint) : event;
|
|
6308
6188
|
});
|
|
6309
6189
|
}
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6190
|
+
}
|
|
6191
|
+
/**
|
|
6192
|
+
* @inheritDoc
|
|
6193
|
+
*/
|
|
6194
|
+
LinkedErrors.id = 'LinkedErrors';
|
|
6195
|
+
/**
|
|
6196
|
+
* @inheritDoc
|
|
6197
|
+
*/
|
|
6198
|
+
function _handler(key, limit, event, hint) {
|
|
6199
|
+
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
|
|
6319
6200
|
return event;
|
|
6320
6201
|
}
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
_walkErrorTree(error, key, stack = []) {
|
|
6325
|
-
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
|
|
6326
|
-
return stack;
|
|
6327
|
-
}
|
|
6328
|
-
const stacktrace = computeStackTrace(error[key]);
|
|
6329
|
-
const exception = exceptionFromStacktrace(stacktrace);
|
|
6330
|
-
return this._walkErrorTree(error[key], key, [exception, ...stack]);
|
|
6331
|
-
}
|
|
6202
|
+
const linkedErrors = _walkErrorTree(limit, hint.originalException, key);
|
|
6203
|
+
event.exception.values = [...linkedErrors, ...event.exception.values];
|
|
6204
|
+
return event;
|
|
6332
6205
|
}
|
|
6333
6206
|
/**
|
|
6334
|
-
*
|
|
6207
|
+
* JSDOC
|
|
6335
6208
|
*/
|
|
6336
|
-
|
|
6209
|
+
function _walkErrorTree(limit, error, key, stack = []) {
|
|
6210
|
+
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
|
|
6211
|
+
return stack;
|
|
6212
|
+
}
|
|
6213
|
+
const stacktrace = computeStackTrace(error[key]);
|
|
6214
|
+
const exception = exceptionFromStacktrace(stacktrace);
|
|
6215
|
+
return _walkErrorTree(limit, error[key], key, [exception, ...stack]);
|
|
6216
|
+
}
|
|
6337
6217
|
|
|
6338
6218
|
const global$6 = getGlobalObject();
|
|
6339
6219
|
/** UserAgent */
|
|
@@ -6349,17 +6229,16 @@ var Sentry = (function (exports) {
|
|
|
6349
6229
|
*/
|
|
6350
6230
|
setupOnce() {
|
|
6351
6231
|
addGlobalEventProcessor((event) => {
|
|
6352
|
-
var _a, _b, _c;
|
|
6353
6232
|
if (getCurrentHub().getIntegration(UserAgent)) {
|
|
6354
6233
|
// if none of the information we want exists, don't bother
|
|
6355
6234
|
if (!global$6.navigator && !global$6.location && !global$6.document) {
|
|
6356
6235
|
return event;
|
|
6357
6236
|
}
|
|
6358
6237
|
// grab as much info as exists and add it to the event
|
|
6359
|
-
const url = (
|
|
6238
|
+
const url = (event.request && event.request.url) || (global$6.location && global$6.location.href);
|
|
6360
6239
|
const { referrer } = global$6.document || {};
|
|
6361
6240
|
const { userAgent } = global$6.navigator || {};
|
|
6362
|
-
const headers = Object.assign(Object.assign(Object.assign({}, (
|
|
6241
|
+
const headers = Object.assign(Object.assign(Object.assign({}, (event.request && event.request.headers)), (referrer && { Referer: referrer })), (userAgent && { 'User-Agent': userAgent }));
|
|
6363
6242
|
const request = Object.assign(Object.assign({}, (url && { url })), { headers });
|
|
6364
6243
|
return Object.assign(Object.assign({}, event), { request });
|
|
6365
6244
|
}
|
|
@@ -6389,7 +6268,7 @@ var Sentry = (function (exports) {
|
|
|
6389
6268
|
if (self) {
|
|
6390
6269
|
// Juuust in case something goes wrong
|
|
6391
6270
|
try {
|
|
6392
|
-
if (
|
|
6271
|
+
if (_shouldDropEvent(currentEvent, self._previousEvent)) {
|
|
6393
6272
|
logger.warn(`Event dropped due to being a duplicate of previously captured event.`);
|
|
6394
6273
|
return null;
|
|
6395
6274
|
}
|
|
@@ -6402,139 +6281,139 @@ var Sentry = (function (exports) {
|
|
|
6402
6281
|
return currentEvent;
|
|
6403
6282
|
});
|
|
6404
6283
|
}
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
if (this._isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6414
|
-
return true;
|
|
6415
|
-
}
|
|
6284
|
+
}
|
|
6285
|
+
/**
|
|
6286
|
+
* @inheritDoc
|
|
6287
|
+
*/
|
|
6288
|
+
Dedupe.id = 'Dedupe';
|
|
6289
|
+
/** JSDoc */
|
|
6290
|
+
function _shouldDropEvent(currentEvent, previousEvent) {
|
|
6291
|
+
if (!previousEvent) {
|
|
6416
6292
|
return false;
|
|
6417
6293
|
}
|
|
6418
|
-
|
|
6419
|
-
_isSameMessageEvent(currentEvent, previousEvent) {
|
|
6420
|
-
const currentMessage = currentEvent.message;
|
|
6421
|
-
const previousMessage = previousEvent.message;
|
|
6422
|
-
// If neither event has a message property, they were both exceptions, so bail out
|
|
6423
|
-
if (!currentMessage && !previousMessage) {
|
|
6424
|
-
return false;
|
|
6425
|
-
}
|
|
6426
|
-
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6427
|
-
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6428
|
-
return false;
|
|
6429
|
-
}
|
|
6430
|
-
if (currentMessage !== previousMessage) {
|
|
6431
|
-
return false;
|
|
6432
|
-
}
|
|
6433
|
-
if (!this._isSameFingerprint(currentEvent, previousEvent)) {
|
|
6434
|
-
return false;
|
|
6435
|
-
}
|
|
6436
|
-
if (!this._isSameStacktrace(currentEvent, previousEvent)) {
|
|
6437
|
-
return false;
|
|
6438
|
-
}
|
|
6294
|
+
if (_isSameMessageEvent(currentEvent, previousEvent)) {
|
|
6439
6295
|
return true;
|
|
6440
6296
|
}
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
const exception = event.exception;
|
|
6444
|
-
if (exception) {
|
|
6445
|
-
try {
|
|
6446
|
-
// @ts-ignore Object could be undefined
|
|
6447
|
-
return exception.values[0].stacktrace.frames;
|
|
6448
|
-
}
|
|
6449
|
-
catch (_oO) {
|
|
6450
|
-
return undefined;
|
|
6451
|
-
}
|
|
6452
|
-
}
|
|
6453
|
-
else if (event.stacktrace) {
|
|
6454
|
-
return event.stacktrace.frames;
|
|
6455
|
-
}
|
|
6456
|
-
return undefined;
|
|
6297
|
+
if (_isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6298
|
+
return true;
|
|
6457
6299
|
}
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6300
|
+
return false;
|
|
6301
|
+
}
|
|
6302
|
+
/** JSDoc */
|
|
6303
|
+
function _isSameMessageEvent(currentEvent, previousEvent) {
|
|
6304
|
+
const currentMessage = currentEvent.message;
|
|
6305
|
+
const previousMessage = previousEvent.message;
|
|
6306
|
+
// If neither event has a message property, they were both exceptions, so bail out
|
|
6307
|
+
if (!currentMessage && !previousMessage) {
|
|
6308
|
+
return false;
|
|
6309
|
+
}
|
|
6310
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6311
|
+
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6312
|
+
return false;
|
|
6313
|
+
}
|
|
6314
|
+
if (currentMessage !== previousMessage) {
|
|
6315
|
+
return false;
|
|
6316
|
+
}
|
|
6317
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6318
|
+
return false;
|
|
6319
|
+
}
|
|
6320
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6321
|
+
return false;
|
|
6322
|
+
}
|
|
6323
|
+
return true;
|
|
6324
|
+
}
|
|
6325
|
+
/** JSDoc */
|
|
6326
|
+
function _isSameExceptionEvent(currentEvent, previousEvent) {
|
|
6327
|
+
const previousException = _getExceptionFromEvent(previousEvent);
|
|
6328
|
+
const currentException = _getExceptionFromEvent(currentEvent);
|
|
6329
|
+
if (!previousException || !currentException) {
|
|
6330
|
+
return false;
|
|
6331
|
+
}
|
|
6332
|
+
if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
|
|
6333
|
+
return false;
|
|
6334
|
+
}
|
|
6335
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6336
|
+
return false;
|
|
6337
|
+
}
|
|
6338
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6339
|
+
return false;
|
|
6340
|
+
}
|
|
6341
|
+
return true;
|
|
6342
|
+
}
|
|
6343
|
+
/** JSDoc */
|
|
6344
|
+
function _isSameStacktrace(currentEvent, previousEvent) {
|
|
6345
|
+
let currentFrames = _getFramesFromEvent(currentEvent);
|
|
6346
|
+
let previousFrames = _getFramesFromEvent(previousEvent);
|
|
6347
|
+
// If neither event has a stacktrace, they are assumed to be the same
|
|
6348
|
+
if (!currentFrames && !previousFrames) {
|
|
6487
6349
|
return true;
|
|
6488
6350
|
}
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
return
|
|
6351
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6352
|
+
if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
|
|
6353
|
+
return false;
|
|
6492
6354
|
}
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
if (
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6355
|
+
currentFrames = currentFrames;
|
|
6356
|
+
previousFrames = previousFrames;
|
|
6357
|
+
// If number of frames differ, they are not the same
|
|
6358
|
+
if (previousFrames.length !== currentFrames.length) {
|
|
6359
|
+
return false;
|
|
6360
|
+
}
|
|
6361
|
+
// Otherwise, compare the two
|
|
6362
|
+
for (let i = 0; i < previousFrames.length; i++) {
|
|
6363
|
+
const frameA = previousFrames[i];
|
|
6364
|
+
const frameB = currentFrames[i];
|
|
6365
|
+
if (frameA.filename !== frameB.filename ||
|
|
6366
|
+
frameA.lineno !== frameB.lineno ||
|
|
6367
|
+
frameA.colno !== frameB.colno ||
|
|
6368
|
+
frameA.function !== frameB.function) {
|
|
6507
6369
|
return false;
|
|
6508
6370
|
}
|
|
6371
|
+
}
|
|
6372
|
+
return true;
|
|
6373
|
+
}
|
|
6374
|
+
/** JSDoc */
|
|
6375
|
+
function _isSameFingerprint(currentEvent, previousEvent) {
|
|
6376
|
+
let currentFingerprint = currentEvent.fingerprint;
|
|
6377
|
+
let previousFingerprint = previousEvent.fingerprint;
|
|
6378
|
+
// If neither event has a fingerprint, they are assumed to be the same
|
|
6379
|
+
if (!currentFingerprint && !previousFingerprint) {
|
|
6509
6380
|
return true;
|
|
6510
6381
|
}
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6382
|
+
// If only one event has a fingerprint, but not the other one, they are not the same
|
|
6383
|
+
if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
|
|
6384
|
+
return false;
|
|
6385
|
+
}
|
|
6386
|
+
currentFingerprint = currentFingerprint;
|
|
6387
|
+
previousFingerprint = previousFingerprint;
|
|
6388
|
+
// Otherwise, compare the two
|
|
6389
|
+
try {
|
|
6390
|
+
return !!(currentFingerprint.join('') === previousFingerprint.join(''));
|
|
6391
|
+
}
|
|
6392
|
+
catch (_oO) {
|
|
6393
|
+
return false;
|
|
6394
|
+
}
|
|
6395
|
+
}
|
|
6396
|
+
/** JSDoc */
|
|
6397
|
+
function _getExceptionFromEvent(event) {
|
|
6398
|
+
return event.exception && event.exception.values && event.exception.values[0];
|
|
6399
|
+
}
|
|
6400
|
+
/** JSDoc */
|
|
6401
|
+
function _getFramesFromEvent(event) {
|
|
6402
|
+
const exception = event.exception;
|
|
6403
|
+
if (exception) {
|
|
6526
6404
|
try {
|
|
6527
|
-
|
|
6405
|
+
// @ts-ignore Object could be undefined
|
|
6406
|
+
return exception.values[0].stacktrace.frames;
|
|
6528
6407
|
}
|
|
6529
6408
|
catch (_oO) {
|
|
6530
|
-
return
|
|
6409
|
+
return undefined;
|
|
6531
6410
|
}
|
|
6532
6411
|
}
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6412
|
+
else if (event.stacktrace) {
|
|
6413
|
+
return event.stacktrace.frames;
|
|
6414
|
+
}
|
|
6415
|
+
return undefined;
|
|
6416
|
+
}
|
|
6538
6417
|
|
|
6539
6418
|
|
|
6540
6419
|
|
|
@@ -6753,8 +6632,10 @@ var Sentry = (function (exports) {
|
|
|
6753
6632
|
if (client) {
|
|
6754
6633
|
return client.flush(timeout);
|
|
6755
6634
|
}
|
|
6756
|
-
|
|
6757
|
-
|
|
6635
|
+
if (isDebugBuild()) {
|
|
6636
|
+
logger.warn('Cannot flush events. No client defined.');
|
|
6637
|
+
}
|
|
6638
|
+
return resolvedSyncPromise(false);
|
|
6758
6639
|
}
|
|
6759
6640
|
/**
|
|
6760
6641
|
* Call `close()` on the current client, if there is one. See {@link Client.close}.
|
|
@@ -6769,8 +6650,10 @@ var Sentry = (function (exports) {
|
|
|
6769
6650
|
if (client) {
|
|
6770
6651
|
return client.close(timeout);
|
|
6771
6652
|
}
|
|
6772
|
-
|
|
6773
|
-
|
|
6653
|
+
if (isDebugBuild()) {
|
|
6654
|
+
logger.warn('Cannot flush events and disable SDK. No client defined.');
|
|
6655
|
+
}
|
|
6656
|
+
return resolvedSyncPromise(false);
|
|
6774
6657
|
}
|
|
6775
6658
|
/**
|
|
6776
6659
|
* Wrap code within a try/catch block so the SDK is able to capture errors.
|
|
@@ -6783,6 +6666,10 @@ var Sentry = (function (exports) {
|
|
|
6783
6666
|
function wrap$1(fn) {
|
|
6784
6667
|
return wrap(fn)();
|
|
6785
6668
|
}
|
|
6669
|
+
function startSessionOnHub(hub) {
|
|
6670
|
+
hub.startSession({ ignoreDuration: true });
|
|
6671
|
+
hub.captureSession();
|
|
6672
|
+
}
|
|
6786
6673
|
/**
|
|
6787
6674
|
* Enable automatic Session Tracking for the initial page load.
|
|
6788
6675
|
*/
|
|
@@ -6790,7 +6677,9 @@ var Sentry = (function (exports) {
|
|
|
6790
6677
|
const window = getGlobalObject();
|
|
6791
6678
|
const document = window.document;
|
|
6792
6679
|
if (typeof document === 'undefined') {
|
|
6793
|
-
|
|
6680
|
+
if (isDebugBuild()) {
|
|
6681
|
+
logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
|
|
6682
|
+
}
|
|
6794
6683
|
return;
|
|
6795
6684
|
}
|
|
6796
6685
|
const hub = getCurrentHub();
|
|
@@ -6800,26 +6689,20 @@ var Sentry = (function (exports) {
|
|
|
6800
6689
|
// https://github.com/getsentry/sentry-javascript/issues/3207 and
|
|
6801
6690
|
// https://github.com/getsentry/sentry-javascript/issues/3234 and
|
|
6802
6691
|
// https://github.com/getsentry/sentry-javascript/issues/3278.
|
|
6803
|
-
if (
|
|
6692
|
+
if (!hub.captureSession) {
|
|
6804
6693
|
return;
|
|
6805
6694
|
}
|
|
6806
6695
|
// The session duration for browser sessions does not track a meaningful
|
|
6807
6696
|
// concept that can be used as a metric.
|
|
6808
6697
|
// Automatically captured sessions are akin to page views, and thus we
|
|
6809
6698
|
// discard their duration.
|
|
6810
|
-
hub
|
|
6811
|
-
hub.captureSession();
|
|
6699
|
+
startSessionOnHub(hub);
|
|
6812
6700
|
// We want to create a session for every navigation as well
|
|
6813
|
-
addInstrumentationHandler({
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
}
|
|
6819
|
-
hub.startSession({ ignoreDuration: true });
|
|
6820
|
-
hub.captureSession();
|
|
6821
|
-
},
|
|
6822
|
-
type: 'history',
|
|
6701
|
+
addInstrumentationHandler('history', ({ from, to }) => {
|
|
6702
|
+
// Don't create an additional session for the initial route or if the location did not change
|
|
6703
|
+
if (!(from === undefined || from === to)) {
|
|
6704
|
+
startSessionOnHub(getCurrentHub());
|
|
6705
|
+
}
|
|
6823
6706
|
});
|
|
6824
6707
|
}
|
|
6825
6708
|
|