@sentry/browser 6.15.0 → 6.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle.es6.js +1265 -1435
- 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 +1304 -1490
- 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 +15 -17
package/build/bundle.es6.js
CHANGED
|
@@ -1,43 +1,8 @@
|
|
|
1
|
-
/*! @sentry/browser 6.
|
|
1
|
+
/*! @sentry/browser 6.17.0 (ad2f4ad) | 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,35 +1783,47 @@ var Sentry = (function (exports) {
|
|
|
1867
1783
|
}
|
|
1868
1784
|
|
|
1869
1785
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1870
|
-
/**
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
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
|
+
}
|
|
1880
1808
|
/**
|
|
1881
1809
|
* Thenable class that behaves like a Promise and follows it's interface
|
|
1882
1810
|
* but is not async internally
|
|
1883
1811
|
*/
|
|
1884
1812
|
class SyncPromise {
|
|
1885
1813
|
constructor(executor) {
|
|
1886
|
-
this._state =
|
|
1814
|
+
this._state = 0 /* PENDING */;
|
|
1887
1815
|
this._handlers = [];
|
|
1888
1816
|
/** JSDoc */
|
|
1889
1817
|
this._resolve = (value) => {
|
|
1890
|
-
this._setResult(
|
|
1818
|
+
this._setResult(1 /* RESOLVED */, value);
|
|
1891
1819
|
};
|
|
1892
1820
|
/** JSDoc */
|
|
1893
1821
|
this._reject = (reason) => {
|
|
1894
|
-
this._setResult(
|
|
1822
|
+
this._setResult(2 /* REJECTED */, reason);
|
|
1895
1823
|
};
|
|
1896
1824
|
/** JSDoc */
|
|
1897
1825
|
this._setResult = (state, value) => {
|
|
1898
|
-
if (this._state !==
|
|
1826
|
+
if (this._state !== 0 /* PENDING */) {
|
|
1899
1827
|
return;
|
|
1900
1828
|
}
|
|
1901
1829
|
if (isThenable(value)) {
|
|
@@ -1906,35 +1834,25 @@ var Sentry = (function (exports) {
|
|
|
1906
1834
|
this._value = value;
|
|
1907
1835
|
this._executeHandlers();
|
|
1908
1836
|
};
|
|
1909
|
-
// TODO: FIXME
|
|
1910
|
-
/** JSDoc */
|
|
1911
|
-
this._attachHandler = (handler) => {
|
|
1912
|
-
this._handlers = this._handlers.concat(handler);
|
|
1913
|
-
this._executeHandlers();
|
|
1914
|
-
};
|
|
1915
1837
|
/** JSDoc */
|
|
1916
1838
|
this._executeHandlers = () => {
|
|
1917
|
-
if (this._state ===
|
|
1839
|
+
if (this._state === 0 /* PENDING */) {
|
|
1918
1840
|
return;
|
|
1919
1841
|
}
|
|
1920
1842
|
const cachedHandlers = this._handlers.slice();
|
|
1921
1843
|
this._handlers = [];
|
|
1922
1844
|
cachedHandlers.forEach(handler => {
|
|
1923
|
-
if (handler
|
|
1845
|
+
if (handler[0]) {
|
|
1924
1846
|
return;
|
|
1925
1847
|
}
|
|
1926
|
-
if (this._state ===
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
handler.onfulfilled(this._value);
|
|
1930
|
-
}
|
|
1848
|
+
if (this._state === 1 /* RESOLVED */) {
|
|
1849
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1850
|
+
handler[1](this._value);
|
|
1931
1851
|
}
|
|
1932
|
-
if (this._state ===
|
|
1933
|
-
|
|
1934
|
-
handler.onrejected(this._value);
|
|
1935
|
-
}
|
|
1852
|
+
if (this._state === 2 /* REJECTED */) {
|
|
1853
|
+
handler[2](this._value);
|
|
1936
1854
|
}
|
|
1937
|
-
handler
|
|
1855
|
+
handler[0] = true;
|
|
1938
1856
|
});
|
|
1939
1857
|
};
|
|
1940
1858
|
try {
|
|
@@ -1945,80 +1863,40 @@ var Sentry = (function (exports) {
|
|
|
1945
1863
|
}
|
|
1946
1864
|
}
|
|
1947
1865
|
/** JSDoc */
|
|
1948
|
-
static resolve(value) {
|
|
1949
|
-
return new SyncPromise(resolve => {
|
|
1950
|
-
resolve(value);
|
|
1951
|
-
});
|
|
1952
|
-
}
|
|
1953
|
-
/** JSDoc */
|
|
1954
|
-
static reject(reason) {
|
|
1955
|
-
return new SyncPromise((_, reject) => {
|
|
1956
|
-
reject(reason);
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1959
|
-
/** JSDoc */
|
|
1960
|
-
static all(collection) {
|
|
1961
|
-
return new SyncPromise((resolve, reject) => {
|
|
1962
|
-
if (!Array.isArray(collection)) {
|
|
1963
|
-
reject(new TypeError(`Promise.all requires an array as input.`));
|
|
1964
|
-
return;
|
|
1965
|
-
}
|
|
1966
|
-
if (collection.length === 0) {
|
|
1967
|
-
resolve([]);
|
|
1968
|
-
return;
|
|
1969
|
-
}
|
|
1970
|
-
let counter = collection.length;
|
|
1971
|
-
const resolvedCollection = [];
|
|
1972
|
-
collection.forEach((item, index) => {
|
|
1973
|
-
void SyncPromise.resolve(item)
|
|
1974
|
-
.then(value => {
|
|
1975
|
-
resolvedCollection[index] = value;
|
|
1976
|
-
counter -= 1;
|
|
1977
|
-
if (counter !== 0) {
|
|
1978
|
-
return;
|
|
1979
|
-
}
|
|
1980
|
-
resolve(resolvedCollection);
|
|
1981
|
-
})
|
|
1982
|
-
.then(null, reject);
|
|
1983
|
-
});
|
|
1984
|
-
});
|
|
1985
|
-
}
|
|
1986
|
-
/** JSDoc */
|
|
1987
1866
|
then(onfulfilled, onrejected) {
|
|
1988
1867
|
return new SyncPromise((resolve, reject) => {
|
|
1989
|
-
this.
|
|
1990
|
-
|
|
1991
|
-
|
|
1868
|
+
this._handlers.push([
|
|
1869
|
+
false,
|
|
1870
|
+
result => {
|
|
1992
1871
|
if (!onfulfilled) {
|
|
1993
1872
|
// TODO: ¯\_(ツ)_/¯
|
|
1994
1873
|
// TODO: FIXME
|
|
1995
1874
|
resolve(result);
|
|
1996
|
-
return;
|
|
1997
|
-
}
|
|
1998
|
-
try {
|
|
1999
|
-
resolve(onfulfilled(result));
|
|
2000
|
-
return;
|
|
2001
1875
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
1876
|
+
else {
|
|
1877
|
+
try {
|
|
1878
|
+
resolve(onfulfilled(result));
|
|
1879
|
+
}
|
|
1880
|
+
catch (e) {
|
|
1881
|
+
reject(e);
|
|
1882
|
+
}
|
|
2005
1883
|
}
|
|
2006
1884
|
},
|
|
2007
|
-
|
|
1885
|
+
reason => {
|
|
2008
1886
|
if (!onrejected) {
|
|
2009
1887
|
reject(reason);
|
|
2010
|
-
return;
|
|
2011
1888
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
1889
|
+
else {
|
|
1890
|
+
try {
|
|
1891
|
+
resolve(onrejected(reason));
|
|
1892
|
+
}
|
|
1893
|
+
catch (e) {
|
|
1894
|
+
reject(e);
|
|
1895
|
+
}
|
|
2019
1896
|
}
|
|
2020
1897
|
},
|
|
2021
|
-
|
|
1898
|
+
]);
|
|
1899
|
+
this._executeHandlers();
|
|
2022
1900
|
});
|
|
2023
1901
|
}
|
|
2024
1902
|
/** JSDoc */
|
|
@@ -2051,24 +1929,25 @@ var Sentry = (function (exports) {
|
|
|
2051
1929
|
});
|
|
2052
1930
|
});
|
|
2053
1931
|
}
|
|
2054
|
-
/** JSDoc */
|
|
2055
|
-
toString() {
|
|
2056
|
-
return '[object SyncPromise]';
|
|
2057
|
-
}
|
|
2058
1932
|
}
|
|
2059
1933
|
|
|
2060
|
-
/**
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
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;
|
|
2066
1942
|
}
|
|
2067
1943
|
/**
|
|
2068
|
-
*
|
|
1944
|
+
* Remove a promise from the queue.
|
|
1945
|
+
*
|
|
1946
|
+
* @param task Can be any PromiseLike<T>
|
|
1947
|
+
* @returns Removed promise.
|
|
2069
1948
|
*/
|
|
2070
|
-
|
|
2071
|
-
return
|
|
1949
|
+
function remove(task) {
|
|
1950
|
+
return buffer.splice(buffer.indexOf(task), 1)[0];
|
|
2072
1951
|
}
|
|
2073
1952
|
/**
|
|
2074
1953
|
* Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
|
|
@@ -2080,41 +1959,25 @@ var Sentry = (function (exports) {
|
|
|
2080
1959
|
* limit check.
|
|
2081
1960
|
* @returns The original promise.
|
|
2082
1961
|
*/
|
|
2083
|
-
add(taskProducer) {
|
|
2084
|
-
if (!
|
|
2085
|
-
return
|
|
1962
|
+
function add(taskProducer) {
|
|
1963
|
+
if (!isReady()) {
|
|
1964
|
+
return rejectedSyncPromise(new SentryError('Not adding Promise due to buffer limit reached.'));
|
|
2086
1965
|
}
|
|
2087
1966
|
// start the task and add its promise to the queue
|
|
2088
1967
|
const task = taskProducer();
|
|
2089
|
-
if (
|
|
2090
|
-
|
|
1968
|
+
if (buffer.indexOf(task) === -1) {
|
|
1969
|
+
buffer.push(task);
|
|
2091
1970
|
}
|
|
2092
1971
|
void task
|
|
2093
|
-
.then(() =>
|
|
1972
|
+
.then(() => remove(task))
|
|
2094
1973
|
// Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
|
|
2095
1974
|
// rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
|
|
2096
1975
|
// have promises, so TS has to polyfill when down-compiling.)
|
|
2097
|
-
.then(null, () =>
|
|
2098
|
-
// 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.
|
|
2099
1978
|
}));
|
|
2100
1979
|
return task;
|
|
2101
1980
|
}
|
|
2102
|
-
/**
|
|
2103
|
-
* Remove a promise from the queue.
|
|
2104
|
-
*
|
|
2105
|
-
* @param task Can be any PromiseLike<T>
|
|
2106
|
-
* @returns Removed promise.
|
|
2107
|
-
*/
|
|
2108
|
-
remove(task) {
|
|
2109
|
-
const removedTask = this._buffer.splice(this._buffer.indexOf(task), 1)[0];
|
|
2110
|
-
return removedTask;
|
|
2111
|
-
}
|
|
2112
|
-
/**
|
|
2113
|
-
* This function returns the number of unresolved promises in the queue.
|
|
2114
|
-
*/
|
|
2115
|
-
length() {
|
|
2116
|
-
return this._buffer.length;
|
|
2117
|
-
}
|
|
2118
1981
|
/**
|
|
2119
1982
|
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
|
|
2120
1983
|
*
|
|
@@ -2124,8 +1987,12 @@ var Sentry = (function (exports) {
|
|
|
2124
1987
|
* @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
|
|
2125
1988
|
* `false` otherwise
|
|
2126
1989
|
*/
|
|
2127
|
-
drain(timeout) {
|
|
2128
|
-
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
|
+
}
|
|
2129
1996
|
// wait for `timeout` ms and then resolve to `false` (if not cancelled first)
|
|
2130
1997
|
const capturedSetTimeout = setTimeout(() => {
|
|
2131
1998
|
if (timeout && timeout > 0) {
|
|
@@ -2133,16 +2000,62 @@ var Sentry = (function (exports) {
|
|
|
2133
2000
|
}
|
|
2134
2001
|
}, timeout);
|
|
2135
2002
|
// if all promises resolve in time, cancel the timer and resolve to `true`
|
|
2136
|
-
|
|
2137
|
-
.then(() => {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
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);
|
|
2143
2011
|
});
|
|
2144
2012
|
});
|
|
2145
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';
|
|
2146
2059
|
}
|
|
2147
2060
|
|
|
2148
2061
|
/**
|
|
@@ -2301,6 +2214,11 @@ var Sentry = (function (exports) {
|
|
|
2301
2214
|
this._extra = {};
|
|
2302
2215
|
/** Contexts */
|
|
2303
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 = {};
|
|
2304
2222
|
}
|
|
2305
2223
|
/**
|
|
2306
2224
|
* Inherit values from the parent scope.
|
|
@@ -2463,19 +2381,10 @@ var Sentry = (function (exports) {
|
|
|
2463
2381
|
* @inheritDoc
|
|
2464
2382
|
*/
|
|
2465
2383
|
getTransaction() {
|
|
2466
|
-
|
|
2467
|
-
//
|
|
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.
|
|
2468
2386
|
const span = this.getSpan();
|
|
2469
|
-
|
|
2470
|
-
if ((_a = span) === null || _a === void 0 ? void 0 : _a.transaction) {
|
|
2471
|
-
return (_b = span) === null || _b === void 0 ? void 0 : _b.transaction;
|
|
2472
|
-
}
|
|
2473
|
-
// fallback to the old way (known bug: this only finds transactions with sampled = true)
|
|
2474
|
-
if ((_d = (_c = span) === null || _c === void 0 ? void 0 : _c.spanRecorder) === null || _d === void 0 ? void 0 : _d.spans[0]) {
|
|
2475
|
-
return span.spanRecorder.spans[0];
|
|
2476
|
-
}
|
|
2477
|
-
// neither way found a transaction
|
|
2478
|
-
return undefined;
|
|
2387
|
+
return span && span.transaction;
|
|
2479
2388
|
}
|
|
2480
2389
|
/**
|
|
2481
2390
|
* @inheritDoc
|
|
@@ -2594,7 +2503,6 @@ var Sentry = (function (exports) {
|
|
|
2594
2503
|
* @hidden
|
|
2595
2504
|
*/
|
|
2596
2505
|
applyToEvent(event, hint) {
|
|
2597
|
-
var _a;
|
|
2598
2506
|
if (this._extra && Object.keys(this._extra).length) {
|
|
2599
2507
|
event.extra = Object.assign(Object.assign({}, this._extra), event.extra);
|
|
2600
2508
|
}
|
|
@@ -2618,7 +2526,7 @@ var Sentry = (function (exports) {
|
|
|
2618
2526
|
// errors with transaction and it relies on that.
|
|
2619
2527
|
if (this._span) {
|
|
2620
2528
|
event.contexts = Object.assign({ trace: this._span.getTraceContext() }, event.contexts);
|
|
2621
|
-
const transactionName =
|
|
2529
|
+
const transactionName = this._span.transaction && this._span.transaction.name;
|
|
2622
2530
|
if (transactionName) {
|
|
2623
2531
|
event.tags = Object.assign({ transaction: transactionName }, event.tags);
|
|
2624
2532
|
}
|
|
@@ -2626,8 +2534,16 @@ var Sentry = (function (exports) {
|
|
|
2626
2534
|
this._applyFingerprint(event);
|
|
2627
2535
|
event.breadcrumbs = [...(event.breadcrumbs || []), ...this._breadcrumbs];
|
|
2628
2536
|
event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
|
|
2537
|
+
event.sdkProcessingMetadata = this._sdkProcessingMetadata;
|
|
2629
2538
|
return this._notifyEventProcessors([...getGlobalEventProcessors(), ...this._eventProcessors], event, hint);
|
|
2630
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
|
+
}
|
|
2631
2547
|
/**
|
|
2632
2548
|
* This will be called after {@link applyToEvent} is finished.
|
|
2633
2549
|
*/
|
|
@@ -2715,7 +2631,7 @@ var Sentry = (function (exports) {
|
|
|
2715
2631
|
this.errors = 0;
|
|
2716
2632
|
this.sid = uuid4();
|
|
2717
2633
|
this.duration = 0;
|
|
2718
|
-
this.status =
|
|
2634
|
+
this.status = 'ok';
|
|
2719
2635
|
this.init = true;
|
|
2720
2636
|
this.ignoreDuration = false;
|
|
2721
2637
|
// Both timestamp and started are in seconds since the UNIX epoch.
|
|
@@ -2788,8 +2704,8 @@ var Sentry = (function (exports) {
|
|
|
2788
2704
|
if (status) {
|
|
2789
2705
|
this.update({ status });
|
|
2790
2706
|
}
|
|
2791
|
-
else if (this.status ===
|
|
2792
|
-
this.update({ status:
|
|
2707
|
+
else if (this.status === 'ok') {
|
|
2708
|
+
this.update({ status: 'exited' });
|
|
2793
2709
|
}
|
|
2794
2710
|
else {
|
|
2795
2711
|
this.update();
|
|
@@ -2807,17 +2723,16 @@ var Sentry = (function (exports) {
|
|
|
2807
2723
|
errors: this.errors,
|
|
2808
2724
|
did: typeof this.did === 'number' || typeof this.did === 'string' ? `${this.did}` : undefined,
|
|
2809
2725
|
duration: this.duration,
|
|
2810
|
-
attrs:
|
|
2726
|
+
attrs: {
|
|
2811
2727
|
release: this.release,
|
|
2812
2728
|
environment: this.environment,
|
|
2813
2729
|
ip_address: this.ipAddress,
|
|
2814
2730
|
user_agent: this.userAgent,
|
|
2815
|
-
}
|
|
2731
|
+
},
|
|
2816
2732
|
});
|
|
2817
2733
|
}
|
|
2818
2734
|
}
|
|
2819
2735
|
|
|
2820
|
-
/* eslint-disable max-lines */
|
|
2821
2736
|
/**
|
|
2822
2737
|
* API compatibility version of this hub.
|
|
2823
2738
|
*
|
|
@@ -3127,11 +3042,17 @@ var Sentry = (function (exports) {
|
|
|
3127
3042
|
* @inheritDoc
|
|
3128
3043
|
*/
|
|
3129
3044
|
endSession() {
|
|
3130
|
-
|
|
3131
|
-
|
|
3045
|
+
const layer = this.getStackTop();
|
|
3046
|
+
const scope = layer && layer.scope;
|
|
3047
|
+
const session = scope && scope.getSession();
|
|
3048
|
+
if (session) {
|
|
3049
|
+
session.close();
|
|
3050
|
+
}
|
|
3132
3051
|
this._sendSessionUpdate();
|
|
3133
3052
|
// the session is over; take it off of the scope
|
|
3134
|
-
|
|
3053
|
+
if (scope) {
|
|
3054
|
+
scope.setSession();
|
|
3055
|
+
}
|
|
3135
3056
|
}
|
|
3136
3057
|
/**
|
|
3137
3058
|
* @inheritDoc
|
|
@@ -3147,8 +3068,8 @@ var Sentry = (function (exports) {
|
|
|
3147
3068
|
if (scope) {
|
|
3148
3069
|
// End existing session if there's one
|
|
3149
3070
|
const currentSession = scope.getSession && scope.getSession();
|
|
3150
|
-
if (currentSession && currentSession.status ===
|
|
3151
|
-
currentSession.update({ status:
|
|
3071
|
+
if (currentSession && currentSession.status === 'ok') {
|
|
3072
|
+
currentSession.update({ status: 'exited' });
|
|
3152
3073
|
}
|
|
3153
3074
|
this.endSession();
|
|
3154
3075
|
// Afterwards we set the new session on the scope
|
|
@@ -3250,9 +3171,9 @@ var Sentry = (function (exports) {
|
|
|
3250
3171
|
* @returns discovered hub
|
|
3251
3172
|
*/
|
|
3252
3173
|
function getHubFromActiveDomain(registry) {
|
|
3253
|
-
var _a, _b, _c;
|
|
3254
3174
|
try {
|
|
3255
|
-
const
|
|
3175
|
+
const sentry = getMainCarrier().__SENTRY__;
|
|
3176
|
+
const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
|
|
3256
3177
|
// If there's no active domain, just return global hub
|
|
3257
3178
|
if (!activeDomain) {
|
|
3258
3179
|
return getHubFromCarrier(registry);
|
|
@@ -3343,7 +3264,7 @@ var Sentry = (function (exports) {
|
|
|
3343
3264
|
* Captures a message event and sends it to Sentry.
|
|
3344
3265
|
*
|
|
3345
3266
|
* @param message The message to send to Sentry.
|
|
3346
|
-
* @param
|
|
3267
|
+
* @param Severity Define the level of the message.
|
|
3347
3268
|
* @returns The generated eventId.
|
|
3348
3269
|
*/
|
|
3349
3270
|
function captureMessage(message, captureContext) {
|
|
@@ -3475,134 +3396,83 @@ var Sentry = (function (exports) {
|
|
|
3475
3396
|
}
|
|
3476
3397
|
|
|
3477
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
|
+
}
|
|
3478
3431
|
/**
|
|
3479
|
-
*
|
|
3480
|
-
*
|
|
3481
|
-
*
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
/** Returns the store endpoint URL. */
|
|
3507
|
-
getStoreEndpoint() {
|
|
3508
|
-
return this._getIngestEndpoint('store');
|
|
3509
|
-
}
|
|
3510
|
-
/**
|
|
3511
|
-
* Returns the store endpoint URL with auth in the query string.
|
|
3512
|
-
*
|
|
3513
|
-
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3514
|
-
*/
|
|
3515
|
-
getStoreEndpointWithUrlEncodedAuth() {
|
|
3516
|
-
return `${this.getStoreEndpoint()}?${this._encodedAuth()}`;
|
|
3517
|
-
}
|
|
3518
|
-
/**
|
|
3519
|
-
* Returns the envelope endpoint URL with auth in the query string.
|
|
3520
|
-
*
|
|
3521
|
-
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3522
|
-
*/
|
|
3523
|
-
getEnvelopeEndpointWithUrlEncodedAuth() {
|
|
3524
|
-
if (this.forceEnvelope()) {
|
|
3525
|
-
return this._tunnel;
|
|
3526
|
-
}
|
|
3527
|
-
return `${this._getEnvelopeEndpoint()}?${this._encodedAuth()}`;
|
|
3528
|
-
}
|
|
3529
|
-
/** Returns only the path component for the store endpoint. */
|
|
3530
|
-
getStoreEndpointPath() {
|
|
3531
|
-
const dsn = this.getDsn();
|
|
3532
|
-
return `${dsn.path ? `/${dsn.path}` : ''}/api/${dsn.projectId}/store/`;
|
|
3533
|
-
}
|
|
3534
|
-
/**
|
|
3535
|
-
* Returns an object that can be used in request headers.
|
|
3536
|
-
* This is needed for node and the old /store endpoint in sentry
|
|
3537
|
-
*/
|
|
3538
|
-
getRequestHeaders(clientName, clientVersion) {
|
|
3539
|
-
// CHANGE THIS to use metadata but keep clientName and clientVersion compatible
|
|
3540
|
-
const dsn = this.getDsn();
|
|
3541
|
-
const header = [`Sentry sentry_version=${SENTRY_API_VERSION}`];
|
|
3542
|
-
header.push(`sentry_client=${clientName}/${clientVersion}`);
|
|
3543
|
-
header.push(`sentry_key=${dsn.publicKey}`);
|
|
3544
|
-
if (dsn.pass) {
|
|
3545
|
-
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;
|
|
3546
3459
|
}
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
'X-Sentry-Auth': header.join(', '),
|
|
3550
|
-
};
|
|
3551
|
-
}
|
|
3552
|
-
/** Returns the url to the report dialog endpoint. */
|
|
3553
|
-
getReportDialogEndpoint(dialogOptions = {}) {
|
|
3554
|
-
const dsn = this.getDsn();
|
|
3555
|
-
const endpoint = `${this.getBaseApiEndpoint()}embed/error-page/`;
|
|
3556
|
-
const encodedOptions = [];
|
|
3557
|
-
encodedOptions.push(`dsn=${dsn.toString()}`);
|
|
3558
|
-
for (const key in dialogOptions) {
|
|
3559
|
-
if (key === 'dsn') {
|
|
3460
|
+
if (key === 'user') {
|
|
3461
|
+
if (!dialogOptions.user) {
|
|
3560
3462
|
continue;
|
|
3561
3463
|
}
|
|
3562
|
-
if (
|
|
3563
|
-
|
|
3564
|
-
continue;
|
|
3565
|
-
}
|
|
3566
|
-
if (dialogOptions.user.name) {
|
|
3567
|
-
encodedOptions.push(`name=${encodeURIComponent(dialogOptions.user.name)}`);
|
|
3568
|
-
}
|
|
3569
|
-
if (dialogOptions.user.email) {
|
|
3570
|
-
encodedOptions.push(`email=${encodeURIComponent(dialogOptions.user.email)}`);
|
|
3571
|
-
}
|
|
3464
|
+
if (dialogOptions.user.name) {
|
|
3465
|
+
encodedOptions += `&name=${encodeURIComponent(dialogOptions.user.name)}`;
|
|
3572
3466
|
}
|
|
3573
|
-
|
|
3574
|
-
encodedOptions
|
|
3467
|
+
if (dialogOptions.user.email) {
|
|
3468
|
+
encodedOptions += `&email=${encodeURIComponent(dialogOptions.user.email)}`;
|
|
3575
3469
|
}
|
|
3576
3470
|
}
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
}
|
|
3580
|
-
return endpoint;
|
|
3581
|
-
}
|
|
3582
|
-
/** Returns the envelope endpoint URL. */
|
|
3583
|
-
_getEnvelopeEndpoint() {
|
|
3584
|
-
return this._getIngestEndpoint('envelope');
|
|
3585
|
-
}
|
|
3586
|
-
/** Returns the ingest API endpoint for target. */
|
|
3587
|
-
_getIngestEndpoint(target) {
|
|
3588
|
-
if (this._tunnel) {
|
|
3589
|
-
return this._tunnel;
|
|
3471
|
+
else {
|
|
3472
|
+
encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key])}`;
|
|
3590
3473
|
}
|
|
3591
|
-
const base = this.getBaseApiEndpoint();
|
|
3592
|
-
const dsn = this.getDsn();
|
|
3593
|
-
return `${base}${dsn.projectId}/${target}/`;
|
|
3594
|
-
}
|
|
3595
|
-
/** Returns a URL-encoded string with auth config suitable for a query string. */
|
|
3596
|
-
_encodedAuth() {
|
|
3597
|
-
const dsn = this.getDsn();
|
|
3598
|
-
const auth = {
|
|
3599
|
-
// We send only the minimum set of required information. See
|
|
3600
|
-
// https://github.com/getsentry/sentry-javascript/issues/2572.
|
|
3601
|
-
sentry_key: dsn.publicKey,
|
|
3602
|
-
sentry_version: SENTRY_API_VERSION,
|
|
3603
|
-
};
|
|
3604
|
-
return urlEncode(auth);
|
|
3605
3474
|
}
|
|
3475
|
+
return `${endpoint}?${encodedOptions}`;
|
|
3606
3476
|
}
|
|
3607
3477
|
|
|
3608
3478
|
const installedIntegrations = [];
|
|
@@ -3666,7 +3536,7 @@ var Sentry = (function (exports) {
|
|
|
3666
3536
|
// set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty`
|
|
3667
3537
|
// because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be
|
|
3668
3538
|
// considered a member of the index the way the actual integrations are
|
|
3669
|
-
|
|
3539
|
+
addNonEnumerableProperty(integrations, 'initialized', true);
|
|
3670
3540
|
return integrations;
|
|
3671
3541
|
}
|
|
3672
3542
|
|
|
@@ -3719,7 +3589,7 @@ var Sentry = (function (exports) {
|
|
|
3719
3589
|
this._backend = new backendClass(options);
|
|
3720
3590
|
this._options = options;
|
|
3721
3591
|
if (options.dsn) {
|
|
3722
|
-
this._dsn =
|
|
3592
|
+
this._dsn = makeDsn(options.dsn);
|
|
3723
3593
|
}
|
|
3724
3594
|
}
|
|
3725
3595
|
/**
|
|
@@ -3760,9 +3630,8 @@ var Sentry = (function (exports) {
|
|
|
3760
3630
|
* @inheritDoc
|
|
3761
3631
|
*/
|
|
3762
3632
|
captureEvent(event, hint, scope) {
|
|
3763
|
-
var _a;
|
|
3764
3633
|
// ensure we haven't captured this very object before
|
|
3765
|
-
if (
|
|
3634
|
+
if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {
|
|
3766
3635
|
logger.log(ALREADY_SEEN_ERROR);
|
|
3767
3636
|
return;
|
|
3768
3637
|
}
|
|
@@ -3777,11 +3646,15 @@ var Sentry = (function (exports) {
|
|
|
3777
3646
|
*/
|
|
3778
3647
|
captureSession(session) {
|
|
3779
3648
|
if (!this._isEnabled()) {
|
|
3780
|
-
|
|
3649
|
+
if (isDebugBuild()) {
|
|
3650
|
+
logger.warn('SDK not enabled, will not capture session.');
|
|
3651
|
+
}
|
|
3781
3652
|
return;
|
|
3782
3653
|
}
|
|
3783
3654
|
if (!(typeof session.release === 'string')) {
|
|
3784
|
-
|
|
3655
|
+
if (isDebugBuild()) {
|
|
3656
|
+
logger.warn('Discarded session because of missing or non-string release');
|
|
3657
|
+
}
|
|
3785
3658
|
}
|
|
3786
3659
|
else {
|
|
3787
3660
|
this._sendSession(session);
|
|
@@ -3864,10 +3737,10 @@ var Sentry = (function (exports) {
|
|
|
3864
3737
|
// A session is updated and that session update is sent in only one of the two following scenarios:
|
|
3865
3738
|
// 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
|
|
3866
3739
|
// 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
|
|
3867
|
-
const sessionNonTerminal = session.status ===
|
|
3740
|
+
const sessionNonTerminal = session.status === 'ok';
|
|
3868
3741
|
const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
|
|
3869
3742
|
if (shouldUpdateAndSend) {
|
|
3870
|
-
session.update(Object.assign(Object.assign({}, (crashed && { status:
|
|
3743
|
+
session.update(Object.assign(Object.assign({}, (crashed && { status: 'crashed' })), { errors: session.errors || Number(errored || crashed) }));
|
|
3871
3744
|
this.captureSession(session);
|
|
3872
3745
|
}
|
|
3873
3746
|
}
|
|
@@ -3938,7 +3811,7 @@ var Sentry = (function (exports) {
|
|
|
3938
3811
|
finalScope = Scope.clone(finalScope).update(hint.captureContext);
|
|
3939
3812
|
}
|
|
3940
3813
|
// We prepare the result here with a resolved Event.
|
|
3941
|
-
let result =
|
|
3814
|
+
let result = resolvedSyncPromise(prepared);
|
|
3942
3815
|
// This should be the last thing called, since we want that
|
|
3943
3816
|
// {@link Hub.addEventProcessor} gets the finished prepared event.
|
|
3944
3817
|
if (finalScope) {
|
|
@@ -4070,26 +3943,29 @@ var Sentry = (function (exports) {
|
|
|
4070
3943
|
* @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
|
|
4071
3944
|
*/
|
|
4072
3945
|
_processEvent(event, hint, scope) {
|
|
4073
|
-
var _a, _b;
|
|
4074
3946
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
4075
3947
|
const { beforeSend, sampleRate } = this.getOptions();
|
|
4076
3948
|
const transport = this.getTransport();
|
|
3949
|
+
function recordLostEvent(outcome, category) {
|
|
3950
|
+
if (transport.recordLostEvent) {
|
|
3951
|
+
transport.recordLostEvent(outcome, category);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
4077
3954
|
if (!this._isEnabled()) {
|
|
4078
|
-
return
|
|
3955
|
+
return rejectedSyncPromise(new SentryError('SDK not enabled, will not capture event.'));
|
|
4079
3956
|
}
|
|
4080
3957
|
const isTransaction = event.type === 'transaction';
|
|
4081
3958
|
// 1.0 === 100% events are sent
|
|
4082
3959
|
// 0.0 === 0% events are sent
|
|
4083
3960
|
// Sampling for transaction happens somewhere else
|
|
4084
3961
|
if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) {
|
|
4085
|
-
|
|
4086
|
-
return
|
|
3962
|
+
recordLostEvent('sample_rate', 'event');
|
|
3963
|
+
return rejectedSyncPromise(new SentryError(`Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`));
|
|
4087
3964
|
}
|
|
4088
3965
|
return this._prepareEvent(event, scope, hint)
|
|
4089
3966
|
.then(prepared => {
|
|
4090
|
-
var _a, _b;
|
|
4091
3967
|
if (prepared === null) {
|
|
4092
|
-
|
|
3968
|
+
recordLostEvent('event_processor', event.type || 'event');
|
|
4093
3969
|
throw new SentryError('An event processor returned null, will not send event.');
|
|
4094
3970
|
}
|
|
4095
3971
|
const isInternalException = hint && hint.data && hint.data.__sentry__ === true;
|
|
@@ -4097,12 +3973,11 @@ var Sentry = (function (exports) {
|
|
|
4097
3973
|
return prepared;
|
|
4098
3974
|
}
|
|
4099
3975
|
const beforeSendResult = beforeSend(prepared, hint);
|
|
4100
|
-
return
|
|
3976
|
+
return _ensureBeforeSendRv(beforeSendResult);
|
|
4101
3977
|
})
|
|
4102
3978
|
.then(processedEvent => {
|
|
4103
|
-
var _a, _b;
|
|
4104
3979
|
if (processedEvent === null) {
|
|
4105
|
-
|
|
3980
|
+
recordLostEvent('before_send', event.type || 'event');
|
|
4106
3981
|
throw new SentryError('`beforeSend` returned `null`, will not send event.');
|
|
4107
3982
|
}
|
|
4108
3983
|
const session = scope && scope.getSession && scope.getSession();
|
|
@@ -4138,26 +4013,26 @@ var Sentry = (function (exports) {
|
|
|
4138
4013
|
return reason;
|
|
4139
4014
|
});
|
|
4140
4015
|
}
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
});
|
|
4155
|
-
}
|
|
4156
|
-
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4157
|
-
throw new SentryError(nullErr);
|
|
4158
|
-
}
|
|
4159
|
-
return rv;
|
|
4016
|
+
}
|
|
4017
|
+
/**
|
|
4018
|
+
* Verifies that return value of configured `beforeSend` is of expected type.
|
|
4019
|
+
*/
|
|
4020
|
+
function _ensureBeforeSendRv(rv) {
|
|
4021
|
+
const nullErr = '`beforeSend` method has to return `null` or a valid event.';
|
|
4022
|
+
if (isThenable(rv)) {
|
|
4023
|
+
return rv.then(event => {
|
|
4024
|
+
if (!(isPlainObject(event) || event === null)) {
|
|
4025
|
+
throw new SentryError(nullErr);
|
|
4026
|
+
}
|
|
4027
|
+
return event;
|
|
4028
|
+
}, e => {
|
|
4029
|
+
throw new SentryError(`beforeSend rejected with ${e}`);
|
|
4030
|
+
});
|
|
4160
4031
|
}
|
|
4032
|
+
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4033
|
+
throw new SentryError(nullErr);
|
|
4034
|
+
}
|
|
4035
|
+
return rv;
|
|
4161
4036
|
}
|
|
4162
4037
|
|
|
4163
4038
|
/** Noop transport */
|
|
@@ -4166,16 +4041,16 @@ var Sentry = (function (exports) {
|
|
|
4166
4041
|
* @inheritDoc
|
|
4167
4042
|
*/
|
|
4168
4043
|
sendEvent(_) {
|
|
4169
|
-
return
|
|
4044
|
+
return resolvedSyncPromise({
|
|
4170
4045
|
reason: `NoopTransport: Event has been skipped because no Dsn is configured.`,
|
|
4171
|
-
status:
|
|
4046
|
+
status: 'skipped',
|
|
4172
4047
|
});
|
|
4173
4048
|
}
|
|
4174
4049
|
/**
|
|
4175
4050
|
* @inheritDoc
|
|
4176
4051
|
*/
|
|
4177
4052
|
close(_) {
|
|
4178
|
-
return
|
|
4053
|
+
return resolvedSyncPromise(true);
|
|
4179
4054
|
}
|
|
4180
4055
|
}
|
|
4181
4056
|
|
|
@@ -4210,7 +4085,9 @@ var Sentry = (function (exports) {
|
|
|
4210
4085
|
*/
|
|
4211
4086
|
sendEvent(event) {
|
|
4212
4087
|
void this._transport.sendEvent(event).then(null, reason => {
|
|
4213
|
-
|
|
4088
|
+
if (isDebugBuild()) {
|
|
4089
|
+
logger.error(`Error while sending event: ${reason}`);
|
|
4090
|
+
}
|
|
4214
4091
|
});
|
|
4215
4092
|
}
|
|
4216
4093
|
/**
|
|
@@ -4218,11 +4095,15 @@ var Sentry = (function (exports) {
|
|
|
4218
4095
|
*/
|
|
4219
4096
|
sendSession(session) {
|
|
4220
4097
|
if (!this._transport.sendSession) {
|
|
4221
|
-
|
|
4098
|
+
if (isDebugBuild()) {
|
|
4099
|
+
logger.warn("Dropping session because custom transport doesn't implement sendSession");
|
|
4100
|
+
}
|
|
4222
4101
|
return;
|
|
4223
4102
|
}
|
|
4224
4103
|
void this._transport.sendSession(session).then(null, reason => {
|
|
4225
|
-
|
|
4104
|
+
if (isDebugBuild()) {
|
|
4105
|
+
logger.error(`Error while sending session: ${reason}`);
|
|
4106
|
+
}
|
|
4226
4107
|
});
|
|
4227
4108
|
}
|
|
4228
4109
|
/**
|
|
@@ -4239,31 +4120,6 @@ var Sentry = (function (exports) {
|
|
|
4239
4120
|
}
|
|
4240
4121
|
}
|
|
4241
4122
|
|
|
4242
|
-
/*! *****************************************************************************
|
|
4243
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4244
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
4245
|
-
this file except in compliance with the License. You may obtain a copy of the
|
|
4246
|
-
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4247
|
-
|
|
4248
|
-
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
4249
|
-
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
4250
|
-
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
4251
|
-
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
4252
|
-
|
|
4253
|
-
See the Apache Version 2.0 License for specific language governing permissions
|
|
4254
|
-
and limitations under the License.
|
|
4255
|
-
***************************************************************************** */
|
|
4256
|
-
|
|
4257
|
-
function __rest(s, e) {
|
|
4258
|
-
var t = {};
|
|
4259
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4260
|
-
t[p] = s[p];
|
|
4261
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
4262
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
|
4263
|
-
t[p[i]] = s[p[i]];
|
|
4264
|
-
return t;
|
|
4265
|
-
}
|
|
4266
|
-
|
|
4267
4123
|
/** Extract sdk info from from the API metadata */
|
|
4268
4124
|
function getSdkMetadataForEnvelopeHeader(api) {
|
|
4269
4125
|
if (!api.metadata || !api.metadata.sdk) {
|
|
@@ -4290,7 +4146,7 @@ var Sentry = (function (exports) {
|
|
|
4290
4146
|
/** Creates a SentryRequest from a Session. */
|
|
4291
4147
|
function sessionToSentryRequest(session, api) {
|
|
4292
4148
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4293
|
-
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.
|
|
4149
|
+
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
|
|
4294
4150
|
// I know this is hacky but we don't want to add `session` to request type since it's never rate limited
|
|
4295
4151
|
const type = 'aggregates' in session ? 'sessions' : 'session';
|
|
4296
4152
|
const itemHeaders = JSON.stringify({
|
|
@@ -4299,26 +4155,24 @@ var Sentry = (function (exports) {
|
|
|
4299
4155
|
return {
|
|
4300
4156
|
body: `${envelopeHeaders}\n${itemHeaders}\n${JSON.stringify(session)}`,
|
|
4301
4157
|
type,
|
|
4302
|
-
url: api.
|
|
4158
|
+
url: getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel),
|
|
4303
4159
|
};
|
|
4304
4160
|
}
|
|
4305
4161
|
/** Creates a SentryRequest from an event. */
|
|
4306
4162
|
function eventToSentryRequest(event, api) {
|
|
4307
4163
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4308
4164
|
const eventType = event.type || 'event';
|
|
4309
|
-
const useEnvelope = eventType === 'transaction' || api.
|
|
4310
|
-
const
|
|
4165
|
+
const useEnvelope = eventType === 'transaction' || !!api.tunnel;
|
|
4166
|
+
const { transactionSampling } = event.sdkProcessingMetadata || {};
|
|
4311
4167
|
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
}
|
|
4315
|
-
else {
|
|
4316
|
-
event.debug_meta = metadata;
|
|
4317
|
-
}
|
|
4168
|
+
// prevent this data from being sent to sentry
|
|
4169
|
+
delete event.sdkProcessingMetadata;
|
|
4318
4170
|
const req = {
|
|
4319
4171
|
body: JSON.stringify(sdkInfo ? enhanceEventWithSdkInfo(event, api.metadata.sdk) : event),
|
|
4320
4172
|
type: eventType,
|
|
4321
|
-
url: useEnvelope
|
|
4173
|
+
url: useEnvelope
|
|
4174
|
+
? getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel)
|
|
4175
|
+
: getStoreEndpointWithUrlEncodedAuth(api.dsn),
|
|
4322
4176
|
};
|
|
4323
4177
|
// https://develop.sentry.dev/sdk/envelopes/
|
|
4324
4178
|
// Since we don't need to manipulate envelopes nor store them, there is no
|
|
@@ -4326,7 +4180,7 @@ var Sentry = (function (exports) {
|
|
|
4326
4180
|
// deserialization. Instead, we only implement a minimal subset of the spec to
|
|
4327
4181
|
// serialize events inline here.
|
|
4328
4182
|
if (useEnvelope) {
|
|
4329
|
-
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.
|
|
4183
|
+
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) })));
|
|
4330
4184
|
const itemHeaders = JSON.stringify({
|
|
4331
4185
|
type: eventType,
|
|
4332
4186
|
// TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
|
|
@@ -4351,17 +4205,19 @@ var Sentry = (function (exports) {
|
|
|
4351
4205
|
* @param options Options to pass to the client.
|
|
4352
4206
|
*/
|
|
4353
4207
|
function initAndBind(clientClass, options) {
|
|
4354
|
-
var _a;
|
|
4355
4208
|
if (options.debug === true) {
|
|
4356
4209
|
logger.enable();
|
|
4357
4210
|
}
|
|
4358
4211
|
const hub = getCurrentHub();
|
|
4359
|
-
|
|
4212
|
+
const scope = hub.getScope();
|
|
4213
|
+
if (scope) {
|
|
4214
|
+
scope.update(options.initialScope);
|
|
4215
|
+
}
|
|
4360
4216
|
const client = new clientClass(options);
|
|
4361
4217
|
hub.bindClient(client);
|
|
4362
4218
|
}
|
|
4363
4219
|
|
|
4364
|
-
const SDK_VERSION = '6.
|
|
4220
|
+
const SDK_VERSION = '6.17.0';
|
|
4365
4221
|
|
|
4366
4222
|
let originalFunctionToString;
|
|
4367
4223
|
/** Patch toString calls to return proper name for wrapped functions */
|
|
@@ -4380,7 +4236,7 @@ var Sentry = (function (exports) {
|
|
|
4380
4236
|
originalFunctionToString = Function.prototype.toString;
|
|
4381
4237
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4382
4238
|
Function.prototype.toString = function (...args) {
|
|
4383
|
-
const context = this
|
|
4239
|
+
const context = getOriginalFunction(this) || this;
|
|
4384
4240
|
return originalFunctionToString.apply(context, args);
|
|
4385
4241
|
};
|
|
4386
4242
|
}
|
|
@@ -4432,19 +4288,27 @@ var Sentry = (function (exports) {
|
|
|
4432
4288
|
/** JSDoc */
|
|
4433
4289
|
_shouldDropEvent(event, options) {
|
|
4434
4290
|
if (this._isSentryError(event, options)) {
|
|
4435
|
-
|
|
4291
|
+
if (isDebugBuild()) {
|
|
4292
|
+
logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
|
|
4293
|
+
}
|
|
4436
4294
|
return true;
|
|
4437
4295
|
}
|
|
4438
4296
|
if (this._isIgnoredError(event, options)) {
|
|
4439
|
-
|
|
4297
|
+
if (isDebugBuild()) {
|
|
4298
|
+
logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
|
|
4299
|
+
}
|
|
4440
4300
|
return true;
|
|
4441
4301
|
}
|
|
4442
4302
|
if (this._isDeniedUrl(event, options)) {
|
|
4443
|
-
|
|
4303
|
+
if (isDebugBuild()) {
|
|
4304
|
+
logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4305
|
+
}
|
|
4444
4306
|
return true;
|
|
4445
4307
|
}
|
|
4446
4308
|
if (!this._isAllowedUrl(event, options)) {
|
|
4447
|
-
|
|
4309
|
+
if (isDebugBuild()) {
|
|
4310
|
+
logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4311
|
+
}
|
|
4448
4312
|
return true;
|
|
4449
4313
|
}
|
|
4450
4314
|
return false;
|
|
@@ -4455,16 +4319,14 @@ var Sentry = (function (exports) {
|
|
|
4455
4319
|
return false;
|
|
4456
4320
|
}
|
|
4457
4321
|
try {
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
event.exception.values[0] &&
|
|
4462
|
-
event.exception.values[0].type === 'SentryError') ||
|
|
4463
|
-
false);
|
|
4322
|
+
// @ts-ignore can't be a sentry error if undefined
|
|
4323
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
4324
|
+
return event.exception.values[0].type === 'SentryError';
|
|
4464
4325
|
}
|
|
4465
|
-
catch (
|
|
4466
|
-
|
|
4326
|
+
catch (e) {
|
|
4327
|
+
// ignore
|
|
4467
4328
|
}
|
|
4329
|
+
return false;
|
|
4468
4330
|
}
|
|
4469
4331
|
/** JSDoc */
|
|
4470
4332
|
_isIgnoredError(event, options) {
|
|
@@ -4531,7 +4393,9 @@ var Sentry = (function (exports) {
|
|
|
4531
4393
|
return [`${value}`, `${type}: ${value}`];
|
|
4532
4394
|
}
|
|
4533
4395
|
catch (oO) {
|
|
4534
|
-
|
|
4396
|
+
if (isDebugBuild()) {
|
|
4397
|
+
logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
|
|
4398
|
+
}
|
|
4535
4399
|
return [];
|
|
4536
4400
|
}
|
|
4537
4401
|
}
|
|
@@ -4539,10 +4403,9 @@ var Sentry = (function (exports) {
|
|
|
4539
4403
|
}
|
|
4540
4404
|
/** JSDoc */
|
|
4541
4405
|
_getLastValidUrl(frames = []) {
|
|
4542
|
-
var _a, _b;
|
|
4543
4406
|
for (let i = frames.length - 1; i >= 0; i--) {
|
|
4544
4407
|
const frame = frames[i];
|
|
4545
|
-
if (
|
|
4408
|
+
if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
|
|
4546
4409
|
return frame.filename || null;
|
|
4547
4410
|
}
|
|
4548
4411
|
}
|
|
@@ -4552,17 +4415,22 @@ var Sentry = (function (exports) {
|
|
|
4552
4415
|
_getEventFilterUrl(event) {
|
|
4553
4416
|
try {
|
|
4554
4417
|
if (event.stacktrace) {
|
|
4555
|
-
|
|
4556
|
-
return this._getLastValidUrl(frames);
|
|
4418
|
+
return this._getLastValidUrl(event.stacktrace.frames);
|
|
4557
4419
|
}
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4420
|
+
let frames;
|
|
4421
|
+
try {
|
|
4422
|
+
// @ts-ignore we only care about frames if the whole thing here is defined
|
|
4423
|
+
frames = event.exception.values[0].stacktrace.frames;
|
|
4561
4424
|
}
|
|
4562
|
-
|
|
4425
|
+
catch (e) {
|
|
4426
|
+
// ignore
|
|
4427
|
+
}
|
|
4428
|
+
return frames ? this._getLastValidUrl(frames) : null;
|
|
4563
4429
|
}
|
|
4564
4430
|
catch (oO) {
|
|
4565
|
-
|
|
4431
|
+
if (isDebugBuild()) {
|
|
4432
|
+
logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
|
|
4433
|
+
}
|
|
4566
4434
|
return null;
|
|
4567
4435
|
}
|
|
4568
4436
|
}
|
|
@@ -4924,7 +4792,7 @@ var Sentry = (function (exports) {
|
|
|
4924
4792
|
}
|
|
4925
4793
|
|
|
4926
4794
|
/**
|
|
4927
|
-
*
|
|
4795
|
+
* Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
|
|
4928
4796
|
* @hidden
|
|
4929
4797
|
*/
|
|
4930
4798
|
function eventFromException(options, exception, hint) {
|
|
@@ -4937,7 +4805,7 @@ var Sentry = (function (exports) {
|
|
|
4937
4805
|
if (hint && hint.event_id) {
|
|
4938
4806
|
event.event_id = hint.event_id;
|
|
4939
4807
|
}
|
|
4940
|
-
return
|
|
4808
|
+
return resolvedSyncPromise(event);
|
|
4941
4809
|
}
|
|
4942
4810
|
/**
|
|
4943
4811
|
* Builds and Event from a Message
|
|
@@ -4952,7 +4820,7 @@ var Sentry = (function (exports) {
|
|
|
4952
4820
|
if (hint && hint.event_id) {
|
|
4953
4821
|
event.event_id = hint.event_id;
|
|
4954
4822
|
}
|
|
4955
|
-
return
|
|
4823
|
+
return resolvedSyncPromise(event);
|
|
4956
4824
|
}
|
|
4957
4825
|
/**
|
|
4958
4826
|
* @hidden
|
|
@@ -4996,11 +4864,11 @@ var Sentry = (function (exports) {
|
|
|
4996
4864
|
return event;
|
|
4997
4865
|
}
|
|
4998
4866
|
if (isPlainObject(exception) || isEvent(exception)) {
|
|
4999
|
-
// If it
|
|
5000
|
-
// This will allow us to group events based on top-level keys
|
|
5001
|
-
//
|
|
4867
|
+
// If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
|
|
4868
|
+
// it manually. This will allow us to group events based on top-level keys which is much better than creating a new
|
|
4869
|
+
// group on any key/value change.
|
|
5002
4870
|
const objectException = exception;
|
|
5003
|
-
event = eventFromPlainObject(objectException, syntheticException, options.
|
|
4871
|
+
event = eventFromPlainObject(objectException, syntheticException, options.isRejection);
|
|
5004
4872
|
addExceptionMechanism(event, {
|
|
5005
4873
|
synthetic: true,
|
|
5006
4874
|
});
|
|
@@ -5080,7 +4948,6 @@ var Sentry = (function (exports) {
|
|
|
5080
4948
|
* Safari: resource blocked by content blocker
|
|
5081
4949
|
*/
|
|
5082
4950
|
function getNativeFetchImplementation() {
|
|
5083
|
-
var _a, _b;
|
|
5084
4951
|
if (cachedFetchImpl) {
|
|
5085
4952
|
return cachedFetchImpl;
|
|
5086
4953
|
}
|
|
@@ -5092,18 +4959,21 @@ var Sentry = (function (exports) {
|
|
|
5092
4959
|
const document = global$3.document;
|
|
5093
4960
|
let fetchImpl = global$3.fetch;
|
|
5094
4961
|
// eslint-disable-next-line deprecation/deprecation
|
|
5095
|
-
if (
|
|
4962
|
+
if (document && typeof document.createElement === `function`) {
|
|
5096
4963
|
try {
|
|
5097
4964
|
const sandbox = document.createElement('iframe');
|
|
5098
4965
|
sandbox.hidden = true;
|
|
5099
4966
|
document.head.appendChild(sandbox);
|
|
5100
|
-
|
|
5101
|
-
|
|
4967
|
+
const contentWindow = sandbox.contentWindow;
|
|
4968
|
+
if (contentWindow && contentWindow.fetch) {
|
|
4969
|
+
fetchImpl = contentWindow.fetch;
|
|
5102
4970
|
}
|
|
5103
4971
|
document.head.removeChild(sandbox);
|
|
5104
4972
|
}
|
|
5105
4973
|
catch (e) {
|
|
5106
|
-
|
|
4974
|
+
if (isDebugBuild()) {
|
|
4975
|
+
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
|
|
4976
|
+
}
|
|
5107
4977
|
}
|
|
5108
4978
|
}
|
|
5109
4979
|
return (cachedFetchImpl = fetchImpl.bind(global$3));
|
|
@@ -5134,25 +5004,23 @@ var Sentry = (function (exports) {
|
|
|
5134
5004
|
}
|
|
5135
5005
|
}
|
|
5136
5006
|
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
attachment: 'attachment',
|
|
5142
|
-
};
|
|
5007
|
+
function requestTypeToCategory(ty) {
|
|
5008
|
+
const tyStr = ty;
|
|
5009
|
+
return tyStr === 'event' ? 'error' : tyStr;
|
|
5010
|
+
}
|
|
5143
5011
|
const global$4 = getGlobalObject();
|
|
5144
5012
|
/** Base Transport class implementation */
|
|
5145
5013
|
class BaseTransport {
|
|
5146
5014
|
constructor(options) {
|
|
5147
5015
|
this.options = options;
|
|
5148
5016
|
/** A simple buffer holding all requests. */
|
|
5149
|
-
this._buffer =
|
|
5017
|
+
this._buffer = makePromiseBuffer(30);
|
|
5150
5018
|
/** Locks transport after receiving rate limits in a response */
|
|
5151
5019
|
this._rateLimits = {};
|
|
5152
5020
|
this._outcomes = {};
|
|
5153
|
-
this._api =
|
|
5021
|
+
this._api = initAPIDetails(options.dsn, options._metadata, options.tunnel);
|
|
5154
5022
|
// eslint-disable-next-line deprecation/deprecation
|
|
5155
|
-
this.url = this._api.
|
|
5023
|
+
this.url = getStoreEndpointWithUrlEncodedAuth(this._api.dsn);
|
|
5156
5024
|
if (this.options.sendClientReports && global$4.document) {
|
|
5157
5025
|
global$4.document.addEventListener('visibilitychange', () => {
|
|
5158
5026
|
if (global$4.document.visibilityState === 'hidden') {
|
|
@@ -5164,8 +5032,14 @@ var Sentry = (function (exports) {
|
|
|
5164
5032
|
/**
|
|
5165
5033
|
* @inheritDoc
|
|
5166
5034
|
*/
|
|
5167
|
-
sendEvent(
|
|
5168
|
-
|
|
5035
|
+
sendEvent(event) {
|
|
5036
|
+
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5037
|
+
}
|
|
5038
|
+
/**
|
|
5039
|
+
* @inheritDoc
|
|
5040
|
+
*/
|
|
5041
|
+
sendSession(session) {
|
|
5042
|
+
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5169
5043
|
}
|
|
5170
5044
|
/**
|
|
5171
5045
|
* @inheritDoc
|
|
@@ -5186,7 +5060,7 @@ var Sentry = (function (exports) {
|
|
|
5186
5060
|
// We could use nested maps, but it's much easier to read and type this way.
|
|
5187
5061
|
// A correct type for map-based implementation if we want to go that route
|
|
5188
5062
|
// would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
|
|
5189
|
-
const key = `${
|
|
5063
|
+
const key = `${requestTypeToCategory(category)}:${reason}`;
|
|
5190
5064
|
logger.log(`Adding outcome: ${key}`);
|
|
5191
5065
|
this._outcomes[key] = (_a = this._outcomes[key], (_a !== null && _a !== void 0 ? _a : 0)) + 1;
|
|
5192
5066
|
}
|
|
@@ -5205,9 +5079,9 @@ var Sentry = (function (exports) {
|
|
|
5205
5079
|
return;
|
|
5206
5080
|
}
|
|
5207
5081
|
logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
|
|
5208
|
-
const url = this._api.
|
|
5082
|
+
const url = getEnvelopeEndpointWithUrlEncodedAuth(this._api.dsn, this._api.tunnel);
|
|
5209
5083
|
// Envelope header is required to be at least an empty object
|
|
5210
|
-
const envelopeHeader = JSON.stringify(Object.assign({}, (this.
|
|
5084
|
+
const envelopeHeader = JSON.stringify(Object.assign({}, (this._api.tunnel && { dsn: dsnToString(this._api.dsn) })));
|
|
5211
5085
|
const itemHeaders = JSON.stringify({
|
|
5212
5086
|
type: 'client_report',
|
|
5213
5087
|
});
|
|
@@ -5234,15 +5108,16 @@ var Sentry = (function (exports) {
|
|
|
5234
5108
|
* Handle Sentry repsonse for promise-based transports.
|
|
5235
5109
|
*/
|
|
5236
5110
|
_handleResponse({ requestType, response, headers, resolve, reject, }) {
|
|
5237
|
-
const status =
|
|
5111
|
+
const status = eventStatusFromHttpCode(response.status);
|
|
5238
5112
|
/**
|
|
5239
5113
|
* "The name is case-insensitive."
|
|
5240
5114
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
|
|
5241
5115
|
*/
|
|
5242
5116
|
const limited = this._handleRateLimit(headers);
|
|
5243
|
-
if (limited)
|
|
5117
|
+
if (limited && isDebugBuild()) {
|
|
5244
5118
|
logger.warn(`Too many ${requestType} requests, backing off until: ${this._disabledUntil(requestType)}`);
|
|
5245
|
-
|
|
5119
|
+
}
|
|
5120
|
+
if (status === 'success') {
|
|
5246
5121
|
resolve({ status });
|
|
5247
5122
|
return;
|
|
5248
5123
|
}
|
|
@@ -5252,7 +5127,7 @@ var Sentry = (function (exports) {
|
|
|
5252
5127
|
* Gets the time that given category is disabled until for rate limiting
|
|
5253
5128
|
*/
|
|
5254
5129
|
_disabledUntil(requestType) {
|
|
5255
|
-
const category =
|
|
5130
|
+
const category = requestTypeToCategory(requestType);
|
|
5256
5131
|
return this._rateLimits[category] || this._rateLimits.all;
|
|
5257
5132
|
}
|
|
5258
5133
|
/**
|
|
@@ -5303,25 +5178,13 @@ var Sentry = (function (exports) {
|
|
|
5303
5178
|
super(options);
|
|
5304
5179
|
this._fetch = fetchImpl;
|
|
5305
5180
|
}
|
|
5306
|
-
/**
|
|
5307
|
-
* @inheritDoc
|
|
5308
|
-
*/
|
|
5309
|
-
sendEvent(event) {
|
|
5310
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5311
|
-
}
|
|
5312
|
-
/**
|
|
5313
|
-
* @inheritDoc
|
|
5314
|
-
*/
|
|
5315
|
-
sendSession(session) {
|
|
5316
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5317
|
-
}
|
|
5318
5181
|
/**
|
|
5319
5182
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5320
5183
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5321
5184
|
*/
|
|
5322
5185
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5323
5186
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5324
|
-
this.recordLostEvent(
|
|
5187
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5325
5188
|
return Promise.reject({
|
|
5326
5189
|
event: originalPayload,
|
|
5327
5190
|
type: sentryRequest.type,
|
|
@@ -5332,9 +5195,9 @@ var Sentry = (function (exports) {
|
|
|
5332
5195
|
const options = {
|
|
5333
5196
|
body: sentryRequest.body,
|
|
5334
5197
|
method: 'POST',
|
|
5335
|
-
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
|
5336
|
-
// https://caniuse.com/#feat=referrer-policy
|
|
5337
|
-
//
|
|
5198
|
+
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
|
|
5199
|
+
// (see https://caniuse.com/#feat=referrer-policy),
|
|
5200
|
+
// it doesn't. And it throws an exception instead of ignoring this parameter...
|
|
5338
5201
|
// REF: https://github.com/getsentry/raven-js/issues/1233
|
|
5339
5202
|
referrerPolicy: (supportsReferrerPolicy() ? 'origin' : ''),
|
|
5340
5203
|
};
|
|
@@ -5365,10 +5228,10 @@ var Sentry = (function (exports) {
|
|
|
5365
5228
|
.then(undefined, reason => {
|
|
5366
5229
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5367
5230
|
if (reason instanceof SentryError) {
|
|
5368
|
-
this.recordLostEvent(
|
|
5231
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5369
5232
|
}
|
|
5370
5233
|
else {
|
|
5371
|
-
this.recordLostEvent(
|
|
5234
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5372
5235
|
}
|
|
5373
5236
|
throw reason;
|
|
5374
5237
|
});
|
|
@@ -5377,25 +5240,13 @@ var Sentry = (function (exports) {
|
|
|
5377
5240
|
|
|
5378
5241
|
/** `XHR` based transport */
|
|
5379
5242
|
class XHRTransport extends BaseTransport {
|
|
5380
|
-
/**
|
|
5381
|
-
* @inheritDoc
|
|
5382
|
-
*/
|
|
5383
|
-
sendEvent(event) {
|
|
5384
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5385
|
-
}
|
|
5386
|
-
/**
|
|
5387
|
-
* @inheritDoc
|
|
5388
|
-
*/
|
|
5389
|
-
sendSession(session) {
|
|
5390
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5391
|
-
}
|
|
5392
5243
|
/**
|
|
5393
5244
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5394
5245
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5395
5246
|
*/
|
|
5396
5247
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5397
5248
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5398
|
-
this.recordLostEvent(
|
|
5249
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5399
5250
|
return Promise.reject({
|
|
5400
5251
|
event: originalPayload,
|
|
5401
5252
|
type: sentryRequest.type,
|
|
@@ -5426,10 +5277,10 @@ var Sentry = (function (exports) {
|
|
|
5426
5277
|
.then(undefined, reason => {
|
|
5427
5278
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5428
5279
|
if (reason instanceof SentryError) {
|
|
5429
|
-
this.recordLostEvent(
|
|
5280
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5430
5281
|
}
|
|
5431
5282
|
else {
|
|
5432
|
-
this.recordLostEvent(
|
|
5283
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5433
5284
|
}
|
|
5434
5285
|
throw reason;
|
|
5435
5286
|
});
|
|
@@ -5508,18 +5359,26 @@ var Sentry = (function (exports) {
|
|
|
5508
5359
|
* @hidden
|
|
5509
5360
|
*/
|
|
5510
5361
|
function wrap(fn, options = {}, before) {
|
|
5362
|
+
// for future readers what this does is wrap a function and then create
|
|
5363
|
+
// a bi-directional wrapping between them.
|
|
5364
|
+
//
|
|
5365
|
+
// example: wrapped = wrap(original);
|
|
5366
|
+
// original.__sentry_wrapped__ -> wrapped
|
|
5367
|
+
// wrapped.__sentry_original__ -> original
|
|
5511
5368
|
if (typeof fn !== 'function') {
|
|
5512
5369
|
return fn;
|
|
5513
5370
|
}
|
|
5514
5371
|
try {
|
|
5372
|
+
// if we're dealing with a function that was previously wrapped, return
|
|
5373
|
+
// the original wrapper.
|
|
5374
|
+
const wrapper = fn.__sentry_wrapped__;
|
|
5375
|
+
if (wrapper) {
|
|
5376
|
+
return wrapper;
|
|
5377
|
+
}
|
|
5515
5378
|
// We don't wanna wrap it twice
|
|
5516
|
-
if (fn
|
|
5379
|
+
if (getOriginalFunction(fn)) {
|
|
5517
5380
|
return fn;
|
|
5518
5381
|
}
|
|
5519
|
-
// If this has already been wrapped in the past, return that wrapped function
|
|
5520
|
-
if (fn.__sentry_wrapped__) {
|
|
5521
|
-
return fn.__sentry_wrapped__;
|
|
5522
|
-
}
|
|
5523
5382
|
}
|
|
5524
5383
|
catch (e) {
|
|
5525
5384
|
// Just accessing custom props in some Selenium environments
|
|
@@ -5537,14 +5396,6 @@ var Sentry = (function (exports) {
|
|
|
5537
5396
|
}
|
|
5538
5397
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
5539
5398
|
const wrappedArguments = args.map((arg) => wrap(arg, options));
|
|
5540
|
-
if (fn.handleEvent) {
|
|
5541
|
-
// Attempt to invoke user-land function
|
|
5542
|
-
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5543
|
-
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
5544
|
-
// is expected behavior and NOT indicative of a bug with sentry.javascript.
|
|
5545
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5546
|
-
return fn.handleEvent.apply(this, wrappedArguments);
|
|
5547
|
-
}
|
|
5548
5399
|
// Attempt to invoke user-land function
|
|
5549
5400
|
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5550
5401
|
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
@@ -5555,13 +5406,12 @@ var Sentry = (function (exports) {
|
|
|
5555
5406
|
ignoreNextOnError();
|
|
5556
5407
|
withScope((scope) => {
|
|
5557
5408
|
scope.addEventProcessor((event) => {
|
|
5558
|
-
const processedEvent = Object.assign({}, event);
|
|
5559
5409
|
if (options.mechanism) {
|
|
5560
|
-
addExceptionTypeValue(
|
|
5561
|
-
addExceptionMechanism(
|
|
5410
|
+
addExceptionTypeValue(event, undefined, undefined);
|
|
5411
|
+
addExceptionMechanism(event, options.mechanism);
|
|
5562
5412
|
}
|
|
5563
|
-
|
|
5564
|
-
return
|
|
5413
|
+
event.extra = Object.assign(Object.assign({}, event.extra), { arguments: args });
|
|
5414
|
+
return event;
|
|
5565
5415
|
});
|
|
5566
5416
|
captureException(ex);
|
|
5567
5417
|
});
|
|
@@ -5579,24 +5429,10 @@ var Sentry = (function (exports) {
|
|
|
5579
5429
|
}
|
|
5580
5430
|
}
|
|
5581
5431
|
catch (_oO) { } // eslint-disable-line no-empty
|
|
5582
|
-
fn.prototype = fn.prototype || {};
|
|
5583
|
-
sentryWrapped.prototype = fn.prototype;
|
|
5584
|
-
Object.defineProperty(fn, '__sentry_wrapped__', {
|
|
5585
|
-
enumerable: false,
|
|
5586
|
-
value: sentryWrapped,
|
|
5587
|
-
});
|
|
5588
5432
|
// Signal that this function has been wrapped/filled already
|
|
5589
5433
|
// for both debugging and to prevent it to being wrapped/filled twice
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
enumerable: false,
|
|
5593
|
-
value: true,
|
|
5594
|
-
},
|
|
5595
|
-
__sentry_original__: {
|
|
5596
|
-
enumerable: false,
|
|
5597
|
-
value: fn,
|
|
5598
|
-
},
|
|
5599
|
-
});
|
|
5434
|
+
markFunctionWrapped(sentryWrapped, fn);
|
|
5435
|
+
addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);
|
|
5600
5436
|
// Restore original function name (not all browsers allow that)
|
|
5601
5437
|
try {
|
|
5602
5438
|
const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name');
|
|
@@ -5621,16 +5457,20 @@ var Sentry = (function (exports) {
|
|
|
5621
5457
|
return;
|
|
5622
5458
|
}
|
|
5623
5459
|
if (!options.eventId) {
|
|
5624
|
-
|
|
5460
|
+
if (isDebugBuild()) {
|
|
5461
|
+
logger.error(`Missing eventId option in showReportDialog call`);
|
|
5462
|
+
}
|
|
5625
5463
|
return;
|
|
5626
5464
|
}
|
|
5627
5465
|
if (!options.dsn) {
|
|
5628
|
-
|
|
5466
|
+
if (isDebugBuild()) {
|
|
5467
|
+
logger.error(`Missing dsn option in showReportDialog call`);
|
|
5468
|
+
}
|
|
5629
5469
|
return;
|
|
5630
5470
|
}
|
|
5631
5471
|
const script = global$5.document.createElement('script');
|
|
5632
5472
|
script.async = true;
|
|
5633
|
-
script.src =
|
|
5473
|
+
script.src = getReportDialogEndpoint(options.dsn, options);
|
|
5634
5474
|
if (options.onLoad) {
|
|
5635
5475
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
5636
5476
|
script.onload = options.onLoad;
|
|
@@ -5650,10 +5490,14 @@ var Sentry = (function (exports) {
|
|
|
5650
5490
|
* @inheritDoc
|
|
5651
5491
|
*/
|
|
5652
5492
|
this.name = GlobalHandlers.id;
|
|
5653
|
-
/**
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5493
|
+
/**
|
|
5494
|
+
* Stores references functions to installing handlers. Will set to undefined
|
|
5495
|
+
* after they have been run so that they are not used twice.
|
|
5496
|
+
*/
|
|
5497
|
+
this._installFunc = {
|
|
5498
|
+
onerror: _installGlobalOnErrorHandler,
|
|
5499
|
+
onunhandledrejection: _installGlobalOnUnhandledRejectionHandler,
|
|
5500
|
+
};
|
|
5657
5501
|
this._options = Object.assign({ onerror: true, onunhandledrejection: true }, options);
|
|
5658
5502
|
}
|
|
5659
5503
|
/**
|
|
@@ -5661,176 +5505,182 @@ var Sentry = (function (exports) {
|
|
|
5661
5505
|
*/
|
|
5662
5506
|
setupOnce() {
|
|
5663
5507
|
Error.stackTraceLimit = 50;
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5508
|
+
const options = this._options;
|
|
5509
|
+
// We can disable guard-for-in as we construct the options object above + do checks against
|
|
5510
|
+
// `this._installFunc` for the property.
|
|
5511
|
+
// eslint-disable-next-line guard-for-in
|
|
5512
|
+
for (const key in options) {
|
|
5513
|
+
const installFunc = this._installFunc[key];
|
|
5514
|
+
if (installFunc && options[key]) {
|
|
5515
|
+
globalHandlerLog(key);
|
|
5516
|
+
installFunc();
|
|
5517
|
+
this._installFunc[key] = undefined;
|
|
5518
|
+
}
|
|
5671
5519
|
}
|
|
5672
5520
|
}
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5521
|
+
}
|
|
5522
|
+
/**
|
|
5523
|
+
* @inheritDoc
|
|
5524
|
+
*/
|
|
5525
|
+
GlobalHandlers.id = 'GlobalHandlers';
|
|
5526
|
+
/** JSDoc */
|
|
5527
|
+
function _installGlobalOnErrorHandler() {
|
|
5528
|
+
addInstrumentationHandler('error',
|
|
5529
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5530
|
+
(data) => {
|
|
5531
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5532
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5676
5533
|
return;
|
|
5677
5534
|
}
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
callback: (data) => {
|
|
5681
|
-
const error = data.error;
|
|
5682
|
-
const currentHub = getCurrentHub();
|
|
5683
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5684
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5685
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5686
|
-
return;
|
|
5687
|
-
}
|
|
5688
|
-
const client = currentHub.getClient();
|
|
5689
|
-
const event = error === undefined && isString(data.msg)
|
|
5690
|
-
? this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
|
|
5691
|
-
: this._enhanceEventWithInitialFrame(eventFromUnknownInput(error || data.msg, undefined, {
|
|
5692
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5693
|
-
rejection: false,
|
|
5694
|
-
}), data.url, data.line, data.column);
|
|
5695
|
-
addExceptionMechanism(event, {
|
|
5696
|
-
handled: false,
|
|
5697
|
-
type: 'onerror',
|
|
5698
|
-
});
|
|
5699
|
-
currentHub.captureEvent(event, {
|
|
5700
|
-
originalException: error,
|
|
5701
|
-
});
|
|
5702
|
-
},
|
|
5703
|
-
type: 'error',
|
|
5704
|
-
});
|
|
5705
|
-
this._onErrorHandlerInstalled = true;
|
|
5706
|
-
}
|
|
5707
|
-
/** JSDoc */
|
|
5708
|
-
_installGlobalOnUnhandledRejectionHandler() {
|
|
5709
|
-
if (this._onUnhandledRejectionHandlerInstalled) {
|
|
5535
|
+
const { msg, url, line, column, error } = data;
|
|
5536
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5710
5537
|
return;
|
|
5711
5538
|
}
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5725
|
-
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5726
|
-
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5727
|
-
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5728
|
-
else if ('detail' in e && 'reason' in e.detail) {
|
|
5729
|
-
error = e.detail.reason;
|
|
5730
|
-
}
|
|
5731
|
-
}
|
|
5732
|
-
catch (_oO) {
|
|
5733
|
-
// no-empty
|
|
5734
|
-
}
|
|
5735
|
-
const currentHub = getCurrentHub();
|
|
5736
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5737
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5738
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5739
|
-
return true;
|
|
5740
|
-
}
|
|
5741
|
-
const client = currentHub.getClient();
|
|
5742
|
-
const event = isPrimitive(error)
|
|
5743
|
-
? this._eventFromRejectionWithPrimitive(error)
|
|
5744
|
-
: eventFromUnknownInput(error, undefined, {
|
|
5745
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5746
|
-
rejection: true,
|
|
5747
|
-
});
|
|
5748
|
-
event.level = exports.Severity.Error;
|
|
5749
|
-
addExceptionMechanism(event, {
|
|
5750
|
-
handled: false,
|
|
5751
|
-
type: 'onunhandledrejection',
|
|
5752
|
-
});
|
|
5753
|
-
currentHub.captureEvent(event, {
|
|
5754
|
-
originalException: error,
|
|
5755
|
-
});
|
|
5756
|
-
return;
|
|
5757
|
-
},
|
|
5758
|
-
type: 'unhandledrejection',
|
|
5759
|
-
});
|
|
5760
|
-
this._onUnhandledRejectionHandlerInstalled = true;
|
|
5761
|
-
}
|
|
5762
|
-
/**
|
|
5763
|
-
* This function creates a stack from an old, error-less onerror handler.
|
|
5764
|
-
*/
|
|
5765
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5766
|
-
_eventFromIncompleteOnError(msg, url, line, column) {
|
|
5767
|
-
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5768
|
-
// If 'message' is ErrorEvent, get real message from inside
|
|
5769
|
-
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5770
|
-
let name;
|
|
5771
|
-
const groups = message.match(ERROR_TYPES_RE);
|
|
5772
|
-
if (groups) {
|
|
5773
|
-
name = groups[1];
|
|
5774
|
-
message = groups[2];
|
|
5775
|
-
}
|
|
5776
|
-
const event = {
|
|
5777
|
-
exception: {
|
|
5778
|
-
values: [
|
|
5779
|
-
{
|
|
5780
|
-
type: name || 'Error',
|
|
5781
|
-
value: message,
|
|
5782
|
-
},
|
|
5783
|
-
],
|
|
5784
|
-
},
|
|
5785
|
-
};
|
|
5786
|
-
return this._enhanceEventWithInitialFrame(event, url, line, column);
|
|
5787
|
-
}
|
|
5788
|
-
/**
|
|
5789
|
-
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5790
|
-
*
|
|
5791
|
-
* @param reason: The `reason` property of the promise rejection
|
|
5792
|
-
* @returns An Event object with an appropriate `exception` value
|
|
5793
|
-
*/
|
|
5794
|
-
_eventFromRejectionWithPrimitive(reason) {
|
|
5795
|
-
return {
|
|
5796
|
-
exception: {
|
|
5797
|
-
values: [
|
|
5798
|
-
{
|
|
5799
|
-
type: 'UnhandledRejection',
|
|
5800
|
-
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5801
|
-
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5802
|
-
},
|
|
5803
|
-
],
|
|
5804
|
-
},
|
|
5805
|
-
};
|
|
5806
|
-
}
|
|
5807
|
-
/** JSDoc */
|
|
5539
|
+
const event = error === undefined && isString(msg)
|
|
5540
|
+
? _eventFromIncompleteOnError(msg, url, line, column)
|
|
5541
|
+
: _enhanceEventWithInitialFrame(eventFromUnknownInput(error || msg, undefined, {
|
|
5542
|
+
attachStacktrace,
|
|
5543
|
+
isRejection: false,
|
|
5544
|
+
}), url, line, column);
|
|
5545
|
+
addMechanismAndCapture(hub, error, event, 'onerror');
|
|
5546
|
+
});
|
|
5547
|
+
}
|
|
5548
|
+
/** JSDoc */
|
|
5549
|
+
function _installGlobalOnUnhandledRejectionHandler() {
|
|
5550
|
+
addInstrumentationHandler('unhandledrejection',
|
|
5808
5551
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {};
|
|
5814
|
-
event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || [];
|
|
5815
|
-
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5816
|
-
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5817
|
-
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5818
|
-
if (event.exception.values[0].stacktrace.frames.length === 0) {
|
|
5819
|
-
event.exception.values[0].stacktrace.frames.push({
|
|
5820
|
-
colno,
|
|
5821
|
-
filename,
|
|
5822
|
-
function: '?',
|
|
5823
|
-
in_app: true,
|
|
5824
|
-
lineno,
|
|
5825
|
-
});
|
|
5552
|
+
(e) => {
|
|
5553
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5554
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5555
|
+
return;
|
|
5826
5556
|
}
|
|
5827
|
-
|
|
5828
|
-
|
|
5557
|
+
let error = e;
|
|
5558
|
+
// dig the object of the rejection out of known event types
|
|
5559
|
+
try {
|
|
5560
|
+
// PromiseRejectionEvents store the object of the rejection under 'reason'
|
|
5561
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
|
|
5562
|
+
if ('reason' in e) {
|
|
5563
|
+
error = e.reason;
|
|
5564
|
+
}
|
|
5565
|
+
// something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
|
|
5566
|
+
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5567
|
+
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5568
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5569
|
+
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5570
|
+
else if ('detail' in e && 'reason' in e.detail) {
|
|
5571
|
+
error = e.detail.reason;
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5574
|
+
catch (_oO) {
|
|
5575
|
+
// no-empty
|
|
5576
|
+
}
|
|
5577
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5578
|
+
return true;
|
|
5579
|
+
}
|
|
5580
|
+
const event = isPrimitive(error)
|
|
5581
|
+
? _eventFromRejectionWithPrimitive(error)
|
|
5582
|
+
: eventFromUnknownInput(error, undefined, {
|
|
5583
|
+
attachStacktrace,
|
|
5584
|
+
isRejection: true,
|
|
5585
|
+
});
|
|
5586
|
+
event.level = exports.Severity.Error;
|
|
5587
|
+
addMechanismAndCapture(hub, error, event, 'onunhandledrejection');
|
|
5588
|
+
return;
|
|
5589
|
+
});
|
|
5829
5590
|
}
|
|
5830
5591
|
/**
|
|
5831
|
-
*
|
|
5592
|
+
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5593
|
+
*
|
|
5594
|
+
* @param reason: The `reason` property of the promise rejection
|
|
5595
|
+
* @returns An Event object with an appropriate `exception` value
|
|
5596
|
+
*/
|
|
5597
|
+
function _eventFromRejectionWithPrimitive(reason) {
|
|
5598
|
+
return {
|
|
5599
|
+
exception: {
|
|
5600
|
+
values: [
|
|
5601
|
+
{
|
|
5602
|
+
type: 'UnhandledRejection',
|
|
5603
|
+
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5604
|
+
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5605
|
+
},
|
|
5606
|
+
],
|
|
5607
|
+
},
|
|
5608
|
+
};
|
|
5609
|
+
}
|
|
5610
|
+
/**
|
|
5611
|
+
* This function creates a stack from an old, error-less onerror handler.
|
|
5832
5612
|
*/
|
|
5833
|
-
|
|
5613
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5614
|
+
function _eventFromIncompleteOnError(msg, url, line, column) {
|
|
5615
|
+
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5616
|
+
// If 'message' is ErrorEvent, get real message from inside
|
|
5617
|
+
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5618
|
+
let name = 'Error';
|
|
5619
|
+
const groups = message.match(ERROR_TYPES_RE);
|
|
5620
|
+
if (groups) {
|
|
5621
|
+
name = groups[1];
|
|
5622
|
+
message = groups[2];
|
|
5623
|
+
}
|
|
5624
|
+
const event = {
|
|
5625
|
+
exception: {
|
|
5626
|
+
values: [
|
|
5627
|
+
{
|
|
5628
|
+
type: name,
|
|
5629
|
+
value: message,
|
|
5630
|
+
},
|
|
5631
|
+
],
|
|
5632
|
+
},
|
|
5633
|
+
};
|
|
5634
|
+
return _enhanceEventWithInitialFrame(event, url, line, column);
|
|
5635
|
+
}
|
|
5636
|
+
/** JSDoc */
|
|
5637
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5638
|
+
function _enhanceEventWithInitialFrame(event, url, line, column) {
|
|
5639
|
+
// event.exception
|
|
5640
|
+
const e = (event.exception = event.exception || {});
|
|
5641
|
+
// event.exception.values
|
|
5642
|
+
const ev = (e.values = e.values || []);
|
|
5643
|
+
// event.exception.values[0]
|
|
5644
|
+
const ev0 = (ev[0] = ev[0] || {});
|
|
5645
|
+
// event.exception.values[0].stacktrace
|
|
5646
|
+
const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
|
|
5647
|
+
// event.exception.values[0].stacktrace.frames
|
|
5648
|
+
const ev0sf = (ev0s.frames = ev0s.frames || []);
|
|
5649
|
+
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5650
|
+
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5651
|
+
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5652
|
+
// event.exception.values[0].stacktrace.frames
|
|
5653
|
+
if (ev0sf.length === 0) {
|
|
5654
|
+
ev0sf.push({
|
|
5655
|
+
colno,
|
|
5656
|
+
filename,
|
|
5657
|
+
function: '?',
|
|
5658
|
+
in_app: true,
|
|
5659
|
+
lineno,
|
|
5660
|
+
});
|
|
5661
|
+
}
|
|
5662
|
+
return event;
|
|
5663
|
+
}
|
|
5664
|
+
function globalHandlerLog(type) {
|
|
5665
|
+
if (isDebugBuild()) {
|
|
5666
|
+
logger.log(`Global Handler attached: ${type}`);
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
5669
|
+
function addMechanismAndCapture(hub, error, event, type) {
|
|
5670
|
+
addExceptionMechanism(event, {
|
|
5671
|
+
handled: false,
|
|
5672
|
+
type,
|
|
5673
|
+
});
|
|
5674
|
+
hub.captureEvent(event, {
|
|
5675
|
+
originalException: error,
|
|
5676
|
+
});
|
|
5677
|
+
}
|
|
5678
|
+
function getHubAndAttachStacktrace() {
|
|
5679
|
+
const hub = getCurrentHub();
|
|
5680
|
+
const client = hub.getClient();
|
|
5681
|
+
const attachStacktrace = client && client.getOptions().attachStacktrace;
|
|
5682
|
+
return [hub, attachStacktrace];
|
|
5683
|
+
}
|
|
5834
5684
|
|
|
5835
5685
|
const DEFAULT_EVENT_TARGET = [
|
|
5836
5686
|
'EventTarget',
|
|
@@ -5882,172 +5732,173 @@ var Sentry = (function (exports) {
|
|
|
5882
5732
|
setupOnce() {
|
|
5883
5733
|
const global = getGlobalObject();
|
|
5884
5734
|
if (this._options.setTimeout) {
|
|
5885
|
-
fill(global, 'setTimeout',
|
|
5735
|
+
fill(global, 'setTimeout', _wrapTimeFunction);
|
|
5886
5736
|
}
|
|
5887
5737
|
if (this._options.setInterval) {
|
|
5888
|
-
fill(global, 'setInterval',
|
|
5738
|
+
fill(global, 'setInterval', _wrapTimeFunction);
|
|
5889
5739
|
}
|
|
5890
5740
|
if (this._options.requestAnimationFrame) {
|
|
5891
|
-
fill(global, 'requestAnimationFrame',
|
|
5741
|
+
fill(global, 'requestAnimationFrame', _wrapRAF);
|
|
5892
5742
|
}
|
|
5893
5743
|
if (this._options.XMLHttpRequest && 'XMLHttpRequest' in global) {
|
|
5894
|
-
fill(XMLHttpRequest.prototype, 'send',
|
|
5744
|
+
fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
|
|
5895
5745
|
}
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
eventTarget.
|
|
5746
|
+
const eventTargetOption = this._options.eventTarget;
|
|
5747
|
+
if (eventTargetOption) {
|
|
5748
|
+
const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
|
|
5749
|
+
eventTarget.forEach(_wrapEventTarget);
|
|
5899
5750
|
}
|
|
5900
5751
|
}
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
data: { function: getFunctionName(original) },
|
|
5909
|
-
handled: true,
|
|
5910
|
-
type: 'instrument',
|
|
5911
|
-
},
|
|
5912
|
-
});
|
|
5913
|
-
return original.apply(this, args);
|
|
5914
|
-
};
|
|
5915
|
-
}
|
|
5916
|
-
/** JSDoc */
|
|
5752
|
+
}
|
|
5753
|
+
/**
|
|
5754
|
+
* @inheritDoc
|
|
5755
|
+
*/
|
|
5756
|
+
TryCatch.id = 'TryCatch';
|
|
5757
|
+
/** JSDoc */
|
|
5758
|
+
function _wrapTimeFunction(original) {
|
|
5917
5759
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
_wrapEventTarget(target) {
|
|
5936
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5937
|
-
const global = getGlobalObject();
|
|
5760
|
+
return function (...args) {
|
|
5761
|
+
const originalCallback = args[0];
|
|
5762
|
+
args[0] = wrap(originalCallback, {
|
|
5763
|
+
mechanism: {
|
|
5764
|
+
data: { function: getFunctionName(original) },
|
|
5765
|
+
handled: true,
|
|
5766
|
+
type: 'instrument',
|
|
5767
|
+
},
|
|
5768
|
+
});
|
|
5769
|
+
return original.apply(this, args);
|
|
5770
|
+
};
|
|
5771
|
+
}
|
|
5772
|
+
/** JSDoc */
|
|
5773
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5774
|
+
function _wrapRAF(original) {
|
|
5775
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5776
|
+
return function (callback) {
|
|
5938
5777
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
}
|
|
5961
|
-
catch (err) {
|
|
5962
|
-
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5963
|
-
}
|
|
5964
|
-
return original.call(this, eventName,
|
|
5778
|
+
return original.call(this, wrap(callback, {
|
|
5779
|
+
mechanism: {
|
|
5780
|
+
data: {
|
|
5781
|
+
function: 'requestAnimationFrame',
|
|
5782
|
+
handler: getFunctionName(original),
|
|
5783
|
+
},
|
|
5784
|
+
handled: true,
|
|
5785
|
+
type: 'instrument',
|
|
5786
|
+
},
|
|
5787
|
+
}));
|
|
5788
|
+
};
|
|
5789
|
+
}
|
|
5790
|
+
/** JSDoc */
|
|
5791
|
+
function _wrapXHR(originalSend) {
|
|
5792
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5793
|
+
return function (...args) {
|
|
5794
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
5795
|
+
const xhr = this;
|
|
5796
|
+
const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
|
|
5797
|
+
xmlHttpRequestProps.forEach(prop => {
|
|
5798
|
+
if (prop in xhr && typeof xhr[prop] === 'function') {
|
|
5965
5799
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5800
|
+
fill(xhr, prop, function (original) {
|
|
5801
|
+
const wrapOptions = {
|
|
5802
|
+
mechanism: {
|
|
5803
|
+
data: {
|
|
5804
|
+
function: prop,
|
|
5805
|
+
handler: getFunctionName(original),
|
|
5806
|
+
},
|
|
5807
|
+
handled: true,
|
|
5808
|
+
type: 'instrument',
|
|
5972
5809
|
},
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
});
|
|
5979
|
-
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5980
|
-
return function (eventName, fn, options) {
|
|
5981
|
-
var _a;
|
|
5982
|
-
/**
|
|
5983
|
-
* There are 2 possible scenarios here:
|
|
5984
|
-
*
|
|
5985
|
-
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5986
|
-
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5987
|
-
* as a pass-through, and call original `removeEventListener` with it.
|
|
5988
|
-
*
|
|
5989
|
-
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5990
|
-
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5991
|
-
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5992
|
-
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5993
|
-
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5994
|
-
*
|
|
5995
|
-
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5996
|
-
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5997
|
-
* to get rid of the initial handler and it'd stick there forever.
|
|
5998
|
-
*/
|
|
5999
|
-
const wrappedEventHandler = fn;
|
|
6000
|
-
try {
|
|
6001
|
-
const originalEventHandler = (_a = wrappedEventHandler) === null || _a === void 0 ? void 0 : _a.__sentry_wrapped__;
|
|
6002
|
-
if (originalEventHandler) {
|
|
6003
|
-
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5810
|
+
};
|
|
5811
|
+
// If Instrument integration has been called before TryCatch, get the name of original function
|
|
5812
|
+
const originalFunction = getOriginalFunction(original);
|
|
5813
|
+
if (originalFunction) {
|
|
5814
|
+
wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);
|
|
6004
5815
|
}
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
6010
|
-
};
|
|
5816
|
+
// Otherwise wrap directly
|
|
5817
|
+
return wrap(original, wrapOptions);
|
|
5818
|
+
});
|
|
5819
|
+
}
|
|
6011
5820
|
});
|
|
5821
|
+
return originalSend.apply(this, args);
|
|
5822
|
+
};
|
|
5823
|
+
}
|
|
5824
|
+
/** JSDoc */
|
|
5825
|
+
function _wrapEventTarget(target) {
|
|
5826
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5827
|
+
const global = getGlobalObject();
|
|
5828
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5829
|
+
const proto = global[target] && global[target].prototype;
|
|
5830
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
|
|
5831
|
+
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
|
|
5832
|
+
return;
|
|
6012
5833
|
}
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
fill(xhr, prop, function (original) {
|
|
6024
|
-
const wrapOptions = {
|
|
6025
|
-
mechanism: {
|
|
6026
|
-
data: {
|
|
6027
|
-
function: prop,
|
|
6028
|
-
handler: getFunctionName(original),
|
|
6029
|
-
},
|
|
6030
|
-
handled: true,
|
|
6031
|
-
type: 'instrument',
|
|
5834
|
+
fill(proto, 'addEventListener', function (original) {
|
|
5835
|
+
return function (eventName, fn, options) {
|
|
5836
|
+
try {
|
|
5837
|
+
if (typeof fn.handleEvent === 'function') {
|
|
5838
|
+
fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
|
|
5839
|
+
mechanism: {
|
|
5840
|
+
data: {
|
|
5841
|
+
function: 'handleEvent',
|
|
5842
|
+
handler: getFunctionName(fn),
|
|
5843
|
+
target,
|
|
6032
5844
|
},
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
wrapOptions.mechanism.data.handler = getFunctionName(original.__sentry_original__);
|
|
6037
|
-
}
|
|
6038
|
-
// Otherwise wrap directly
|
|
6039
|
-
return wrap(original, wrapOptions);
|
|
5845
|
+
handled: true,
|
|
5846
|
+
type: 'instrument',
|
|
5847
|
+
},
|
|
6040
5848
|
});
|
|
6041
5849
|
}
|
|
6042
|
-
}
|
|
6043
|
-
|
|
5850
|
+
}
|
|
5851
|
+
catch (err) {
|
|
5852
|
+
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5853
|
+
}
|
|
5854
|
+
return original.call(this, eventName,
|
|
5855
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5856
|
+
wrap(fn, {
|
|
5857
|
+
mechanism: {
|
|
5858
|
+
data: {
|
|
5859
|
+
function: 'addEventListener',
|
|
5860
|
+
handler: getFunctionName(fn),
|
|
5861
|
+
target,
|
|
5862
|
+
},
|
|
5863
|
+
handled: true,
|
|
5864
|
+
type: 'instrument',
|
|
5865
|
+
},
|
|
5866
|
+
}), options);
|
|
6044
5867
|
};
|
|
6045
|
-
}
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
5868
|
+
});
|
|
5869
|
+
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5870
|
+
return function (eventName, fn, options) {
|
|
5871
|
+
/**
|
|
5872
|
+
* There are 2 possible scenarios here:
|
|
5873
|
+
*
|
|
5874
|
+
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5875
|
+
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5876
|
+
* as a pass-through, and call original `removeEventListener` with it.
|
|
5877
|
+
*
|
|
5878
|
+
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5879
|
+
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5880
|
+
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5881
|
+
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5882
|
+
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5883
|
+
*
|
|
5884
|
+
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5885
|
+
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5886
|
+
* to get rid of the initial handler and it'd stick there forever.
|
|
5887
|
+
*/
|
|
5888
|
+
const wrappedEventHandler = fn;
|
|
5889
|
+
try {
|
|
5890
|
+
const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
|
|
5891
|
+
if (originalEventHandler) {
|
|
5892
|
+
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5893
|
+
}
|
|
5894
|
+
}
|
|
5895
|
+
catch (e) {
|
|
5896
|
+
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
|
|
5897
|
+
}
|
|
5898
|
+
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
5899
|
+
};
|
|
5900
|
+
});
|
|
5901
|
+
}
|
|
6051
5902
|
|
|
6052
5903
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
6053
5904
|
/**
|
|
@@ -6091,82 +5942,36 @@ var Sentry = (function (exports) {
|
|
|
6091
5942
|
*/
|
|
6092
5943
|
setupOnce() {
|
|
6093
5944
|
if (this._options.console) {
|
|
6094
|
-
addInstrumentationHandler(
|
|
6095
|
-
callback: (...args) => {
|
|
6096
|
-
this._consoleBreadcrumb(...args);
|
|
6097
|
-
},
|
|
6098
|
-
type: 'console',
|
|
6099
|
-
});
|
|
5945
|
+
addInstrumentationHandler('console', _consoleBreadcrumb);
|
|
6100
5946
|
}
|
|
6101
5947
|
if (this._options.dom) {
|
|
6102
|
-
addInstrumentationHandler(
|
|
6103
|
-
callback: (...args) => {
|
|
6104
|
-
this._domBreadcrumb(...args);
|
|
6105
|
-
},
|
|
6106
|
-
type: 'dom',
|
|
6107
|
-
});
|
|
5948
|
+
addInstrumentationHandler('dom', _domBreadcrumb(this._options.dom));
|
|
6108
5949
|
}
|
|
6109
5950
|
if (this._options.xhr) {
|
|
6110
|
-
addInstrumentationHandler(
|
|
6111
|
-
callback: (...args) => {
|
|
6112
|
-
this._xhrBreadcrumb(...args);
|
|
6113
|
-
},
|
|
6114
|
-
type: 'xhr',
|
|
6115
|
-
});
|
|
5951
|
+
addInstrumentationHandler('xhr', _xhrBreadcrumb);
|
|
6116
5952
|
}
|
|
6117
5953
|
if (this._options.fetch) {
|
|
6118
|
-
addInstrumentationHandler(
|
|
6119
|
-
callback: (...args) => {
|
|
6120
|
-
this._fetchBreadcrumb(...args);
|
|
6121
|
-
},
|
|
6122
|
-
type: 'fetch',
|
|
6123
|
-
});
|
|
5954
|
+
addInstrumentationHandler('fetch', _fetchBreadcrumb);
|
|
6124
5955
|
}
|
|
6125
5956
|
if (this._options.history) {
|
|
6126
|
-
addInstrumentationHandler(
|
|
6127
|
-
callback: (...args) => {
|
|
6128
|
-
this._historyBreadcrumb(...args);
|
|
6129
|
-
},
|
|
6130
|
-
type: 'history',
|
|
6131
|
-
});
|
|
6132
|
-
}
|
|
6133
|
-
}
|
|
6134
|
-
/**
|
|
6135
|
-
* Creates breadcrumbs from console API calls
|
|
6136
|
-
*/
|
|
6137
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6138
|
-
_consoleBreadcrumb(handlerData) {
|
|
6139
|
-
const breadcrumb = {
|
|
6140
|
-
category: 'console',
|
|
6141
|
-
data: {
|
|
6142
|
-
arguments: handlerData.args,
|
|
6143
|
-
logger: 'console',
|
|
6144
|
-
},
|
|
6145
|
-
level: exports.Severity.fromString(handlerData.level),
|
|
6146
|
-
message: safeJoin(handlerData.args, ' '),
|
|
6147
|
-
};
|
|
6148
|
-
if (handlerData.level === 'assert') {
|
|
6149
|
-
if (handlerData.args[0] === false) {
|
|
6150
|
-
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6151
|
-
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6152
|
-
}
|
|
6153
|
-
else {
|
|
6154
|
-
// Don't capture a breadcrumb for passed assertions
|
|
6155
|
-
return;
|
|
6156
|
-
}
|
|
5957
|
+
addInstrumentationHandler('history', _historyBreadcrumb);
|
|
6157
5958
|
}
|
|
6158
|
-
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6159
|
-
input: handlerData.args,
|
|
6160
|
-
level: handlerData.level,
|
|
6161
|
-
});
|
|
6162
5959
|
}
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
5960
|
+
}
|
|
5961
|
+
/**
|
|
5962
|
+
* @inheritDoc
|
|
5963
|
+
*/
|
|
5964
|
+
Breadcrumbs.id = 'Breadcrumbs';
|
|
5965
|
+
/**
|
|
5966
|
+
* A HOC that creaes a function that creates breadcrumbs from DOM API calls.
|
|
5967
|
+
* This is a HOC so that we get access to dom options in the closure.
|
|
5968
|
+
*/
|
|
5969
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5970
|
+
function _domBreadcrumb(dom) {
|
|
6166
5971
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6167
|
-
|
|
5972
|
+
function _innerDomBreadcrumb(handlerData) {
|
|
6168
5973
|
let target;
|
|
6169
|
-
let keyAttrs = typeof
|
|
5974
|
+
let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
|
|
6170
5975
|
if (typeof keyAttrs === 'string') {
|
|
6171
5976
|
keyAttrs = [keyAttrs];
|
|
6172
5977
|
}
|
|
@@ -6191,103 +5996,129 @@ var Sentry = (function (exports) {
|
|
|
6191
5996
|
global: handlerData.global,
|
|
6192
5997
|
});
|
|
6193
5998
|
}
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
xhr: handlerData.xhr,
|
|
6215
|
-
input: body,
|
|
6216
|
-
});
|
|
6217
|
-
return;
|
|
6218
|
-
}
|
|
6219
|
-
}
|
|
6220
|
-
/**
|
|
6221
|
-
* Creates breadcrumbs from fetch API calls
|
|
6222
|
-
*/
|
|
6223
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6224
|
-
_fetchBreadcrumb(handlerData) {
|
|
6225
|
-
// We only capture complete fetch requests
|
|
6226
|
-
if (!handlerData.endTimestamp) {
|
|
6227
|
-
return;
|
|
6228
|
-
}
|
|
6229
|
-
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6230
|
-
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6231
|
-
return;
|
|
6232
|
-
}
|
|
6233
|
-
if (handlerData.error) {
|
|
6234
|
-
getCurrentHub().addBreadcrumb({
|
|
6235
|
-
category: 'fetch',
|
|
6236
|
-
data: handlerData.fetchData,
|
|
6237
|
-
level: exports.Severity.Error,
|
|
6238
|
-
type: 'http',
|
|
6239
|
-
}, {
|
|
6240
|
-
data: handlerData.error,
|
|
6241
|
-
input: handlerData.args,
|
|
6242
|
-
});
|
|
5999
|
+
return _innerDomBreadcrumb;
|
|
6000
|
+
}
|
|
6001
|
+
/**
|
|
6002
|
+
* Creates breadcrumbs from console API calls
|
|
6003
|
+
*/
|
|
6004
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6005
|
+
function _consoleBreadcrumb(handlerData) {
|
|
6006
|
+
const breadcrumb = {
|
|
6007
|
+
category: 'console',
|
|
6008
|
+
data: {
|
|
6009
|
+
arguments: handlerData.args,
|
|
6010
|
+
logger: 'console',
|
|
6011
|
+
},
|
|
6012
|
+
level: severityFromString(handlerData.level),
|
|
6013
|
+
message: safeJoin(handlerData.args, ' '),
|
|
6014
|
+
};
|
|
6015
|
+
if (handlerData.level === 'assert') {
|
|
6016
|
+
if (handlerData.args[0] === false) {
|
|
6017
|
+
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6018
|
+
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6243
6019
|
}
|
|
6244
6020
|
else {
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6248
|
-
type: 'http',
|
|
6249
|
-
}, {
|
|
6250
|
-
input: handlerData.args,
|
|
6251
|
-
response: handlerData.response,
|
|
6252
|
-
});
|
|
6021
|
+
// Don't capture a breadcrumb for passed assertions
|
|
6022
|
+
return;
|
|
6253
6023
|
}
|
|
6254
6024
|
}
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
//
|
|
6267
|
-
if (
|
|
6268
|
-
|
|
6269
|
-
}
|
|
6270
|
-
// Use only the path component of the URL if the URL matches the current
|
|
6271
|
-
// document (almost all the time when using pushState)
|
|
6272
|
-
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6273
|
-
to = parsedTo.relative;
|
|
6274
|
-
}
|
|
6275
|
-
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6276
|
-
from = parsedFrom.relative;
|
|
6025
|
+
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6026
|
+
input: handlerData.args,
|
|
6027
|
+
level: handlerData.level,
|
|
6028
|
+
});
|
|
6029
|
+
}
|
|
6030
|
+
/**
|
|
6031
|
+
* Creates breadcrumbs from XHR API calls
|
|
6032
|
+
*/
|
|
6033
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6034
|
+
function _xhrBreadcrumb(handlerData) {
|
|
6035
|
+
if (handlerData.endTimestamp) {
|
|
6036
|
+
// We only capture complete, non-sentry requests
|
|
6037
|
+
if (handlerData.xhr.__sentry_own_request__) {
|
|
6038
|
+
return;
|
|
6277
6039
|
}
|
|
6040
|
+
const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {};
|
|
6278
6041
|
getCurrentHub().addBreadcrumb({
|
|
6279
|
-
category: '
|
|
6042
|
+
category: 'xhr',
|
|
6280
6043
|
data: {
|
|
6281
|
-
|
|
6282
|
-
|
|
6044
|
+
method,
|
|
6045
|
+
url,
|
|
6046
|
+
status_code,
|
|
6283
6047
|
},
|
|
6048
|
+
type: 'http',
|
|
6049
|
+
}, {
|
|
6050
|
+
xhr: handlerData.xhr,
|
|
6051
|
+
input: body,
|
|
6284
6052
|
});
|
|
6053
|
+
return;
|
|
6285
6054
|
}
|
|
6286
6055
|
}
|
|
6287
6056
|
/**
|
|
6288
|
-
*
|
|
6057
|
+
* Creates breadcrumbs from fetch API calls
|
|
6289
6058
|
*/
|
|
6290
|
-
|
|
6059
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6060
|
+
function _fetchBreadcrumb(handlerData) {
|
|
6061
|
+
// We only capture complete fetch requests
|
|
6062
|
+
if (!handlerData.endTimestamp) {
|
|
6063
|
+
return;
|
|
6064
|
+
}
|
|
6065
|
+
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6066
|
+
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6067
|
+
return;
|
|
6068
|
+
}
|
|
6069
|
+
if (handlerData.error) {
|
|
6070
|
+
getCurrentHub().addBreadcrumb({
|
|
6071
|
+
category: 'fetch',
|
|
6072
|
+
data: handlerData.fetchData,
|
|
6073
|
+
level: exports.Severity.Error,
|
|
6074
|
+
type: 'http',
|
|
6075
|
+
}, {
|
|
6076
|
+
data: handlerData.error,
|
|
6077
|
+
input: handlerData.args,
|
|
6078
|
+
});
|
|
6079
|
+
}
|
|
6080
|
+
else {
|
|
6081
|
+
getCurrentHub().addBreadcrumb({
|
|
6082
|
+
category: 'fetch',
|
|
6083
|
+
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6084
|
+
type: 'http',
|
|
6085
|
+
}, {
|
|
6086
|
+
input: handlerData.args,
|
|
6087
|
+
response: handlerData.response,
|
|
6088
|
+
});
|
|
6089
|
+
}
|
|
6090
|
+
}
|
|
6091
|
+
/**
|
|
6092
|
+
* Creates breadcrumbs from history API calls
|
|
6093
|
+
*/
|
|
6094
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6095
|
+
function _historyBreadcrumb(handlerData) {
|
|
6096
|
+
const global = getGlobalObject();
|
|
6097
|
+
let from = handlerData.from;
|
|
6098
|
+
let to = handlerData.to;
|
|
6099
|
+
const parsedLoc = parseUrl(global.location.href);
|
|
6100
|
+
let parsedFrom = parseUrl(from);
|
|
6101
|
+
const parsedTo = parseUrl(to);
|
|
6102
|
+
// Initial pushState doesn't provide `from` information
|
|
6103
|
+
if (!parsedFrom.path) {
|
|
6104
|
+
parsedFrom = parsedLoc;
|
|
6105
|
+
}
|
|
6106
|
+
// Use only the path component of the URL if the URL matches the current
|
|
6107
|
+
// document (almost all the time when using pushState)
|
|
6108
|
+
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6109
|
+
to = parsedTo.relative;
|
|
6110
|
+
}
|
|
6111
|
+
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6112
|
+
from = parsedFrom.relative;
|
|
6113
|
+
}
|
|
6114
|
+
getCurrentHub().addBreadcrumb({
|
|
6115
|
+
category: 'navigation',
|
|
6116
|
+
data: {
|
|
6117
|
+
from,
|
|
6118
|
+
to,
|
|
6119
|
+
},
|
|
6120
|
+
});
|
|
6121
|
+
}
|
|
6291
6122
|
|
|
6292
6123
|
const DEFAULT_KEY = 'cause';
|
|
6293
6124
|
const DEFAULT_LIMIT = 5;
|
|
@@ -6310,40 +6141,36 @@ var Sentry = (function (exports) {
|
|
|
6310
6141
|
setupOnce() {
|
|
6311
6142
|
addGlobalEventProcessor((event, hint) => {
|
|
6312
6143
|
const self = getCurrentHub().getIntegration(LinkedErrors);
|
|
6313
|
-
|
|
6314
|
-
const handler = self._handler && self._handler.bind(self);
|
|
6315
|
-
return typeof handler === 'function' ? handler(event, hint) : event;
|
|
6316
|
-
}
|
|
6317
|
-
return event;
|
|
6144
|
+
return self ? _handler(self._key, self._limit, event, hint) : event;
|
|
6318
6145
|
});
|
|
6319
6146
|
}
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6147
|
+
}
|
|
6148
|
+
/**
|
|
6149
|
+
* @inheritDoc
|
|
6150
|
+
*/
|
|
6151
|
+
LinkedErrors.id = 'LinkedErrors';
|
|
6152
|
+
/**
|
|
6153
|
+
* @inheritDoc
|
|
6154
|
+
*/
|
|
6155
|
+
function _handler(key, limit, event, hint) {
|
|
6156
|
+
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
|
|
6329
6157
|
return event;
|
|
6330
6158
|
}
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
_walkErrorTree(error, key, stack = []) {
|
|
6335
|
-
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
|
|
6336
|
-
return stack;
|
|
6337
|
-
}
|
|
6338
|
-
const stacktrace = computeStackTrace(error[key]);
|
|
6339
|
-
const exception = exceptionFromStacktrace(stacktrace);
|
|
6340
|
-
return this._walkErrorTree(error[key], key, [exception, ...stack]);
|
|
6341
|
-
}
|
|
6159
|
+
const linkedErrors = _walkErrorTree(limit, hint.originalException, key);
|
|
6160
|
+
event.exception.values = [...linkedErrors, ...event.exception.values];
|
|
6161
|
+
return event;
|
|
6342
6162
|
}
|
|
6343
6163
|
/**
|
|
6344
|
-
*
|
|
6164
|
+
* JSDOC
|
|
6345
6165
|
*/
|
|
6346
|
-
|
|
6166
|
+
function _walkErrorTree(limit, error, key, stack = []) {
|
|
6167
|
+
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
|
|
6168
|
+
return stack;
|
|
6169
|
+
}
|
|
6170
|
+
const stacktrace = computeStackTrace(error[key]);
|
|
6171
|
+
const exception = exceptionFromStacktrace(stacktrace);
|
|
6172
|
+
return _walkErrorTree(limit, error[key], key, [exception, ...stack]);
|
|
6173
|
+
}
|
|
6347
6174
|
|
|
6348
6175
|
const global$6 = getGlobalObject();
|
|
6349
6176
|
/** UserAgent */
|
|
@@ -6359,17 +6186,16 @@ var Sentry = (function (exports) {
|
|
|
6359
6186
|
*/
|
|
6360
6187
|
setupOnce() {
|
|
6361
6188
|
addGlobalEventProcessor((event) => {
|
|
6362
|
-
var _a, _b, _c;
|
|
6363
6189
|
if (getCurrentHub().getIntegration(UserAgent)) {
|
|
6364
6190
|
// if none of the information we want exists, don't bother
|
|
6365
6191
|
if (!global$6.navigator && !global$6.location && !global$6.document) {
|
|
6366
6192
|
return event;
|
|
6367
6193
|
}
|
|
6368
6194
|
// grab as much info as exists and add it to the event
|
|
6369
|
-
const url = (
|
|
6195
|
+
const url = (event.request && event.request.url) || (global$6.location && global$6.location.href);
|
|
6370
6196
|
const { referrer } = global$6.document || {};
|
|
6371
6197
|
const { userAgent } = global$6.navigator || {};
|
|
6372
|
-
const headers = Object.assign(Object.assign(Object.assign({}, (
|
|
6198
|
+
const headers = Object.assign(Object.assign(Object.assign({}, (event.request && event.request.headers)), (referrer && { Referer: referrer })), (userAgent && { 'User-Agent': userAgent }));
|
|
6373
6199
|
const request = Object.assign(Object.assign({}, (url && { url })), { headers });
|
|
6374
6200
|
return Object.assign(Object.assign({}, event), { request });
|
|
6375
6201
|
}
|
|
@@ -6399,7 +6225,7 @@ var Sentry = (function (exports) {
|
|
|
6399
6225
|
if (self) {
|
|
6400
6226
|
// Juuust in case something goes wrong
|
|
6401
6227
|
try {
|
|
6402
|
-
if (
|
|
6228
|
+
if (_shouldDropEvent(currentEvent, self._previousEvent)) {
|
|
6403
6229
|
logger.warn(`Event dropped due to being a duplicate of previously captured event.`);
|
|
6404
6230
|
return null;
|
|
6405
6231
|
}
|
|
@@ -6412,139 +6238,139 @@ var Sentry = (function (exports) {
|
|
|
6412
6238
|
return currentEvent;
|
|
6413
6239
|
});
|
|
6414
6240
|
}
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
if (this._isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6424
|
-
return true;
|
|
6425
|
-
}
|
|
6241
|
+
}
|
|
6242
|
+
/**
|
|
6243
|
+
* @inheritDoc
|
|
6244
|
+
*/
|
|
6245
|
+
Dedupe.id = 'Dedupe';
|
|
6246
|
+
/** JSDoc */
|
|
6247
|
+
function _shouldDropEvent(currentEvent, previousEvent) {
|
|
6248
|
+
if (!previousEvent) {
|
|
6426
6249
|
return false;
|
|
6427
6250
|
}
|
|
6428
|
-
|
|
6429
|
-
_isSameMessageEvent(currentEvent, previousEvent) {
|
|
6430
|
-
const currentMessage = currentEvent.message;
|
|
6431
|
-
const previousMessage = previousEvent.message;
|
|
6432
|
-
// If neither event has a message property, they were both exceptions, so bail out
|
|
6433
|
-
if (!currentMessage && !previousMessage) {
|
|
6434
|
-
return false;
|
|
6435
|
-
}
|
|
6436
|
-
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6437
|
-
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6438
|
-
return false;
|
|
6439
|
-
}
|
|
6440
|
-
if (currentMessage !== previousMessage) {
|
|
6441
|
-
return false;
|
|
6442
|
-
}
|
|
6443
|
-
if (!this._isSameFingerprint(currentEvent, previousEvent)) {
|
|
6444
|
-
return false;
|
|
6445
|
-
}
|
|
6446
|
-
if (!this._isSameStacktrace(currentEvent, previousEvent)) {
|
|
6447
|
-
return false;
|
|
6448
|
-
}
|
|
6251
|
+
if (_isSameMessageEvent(currentEvent, previousEvent)) {
|
|
6449
6252
|
return true;
|
|
6450
6253
|
}
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
const exception = event.exception;
|
|
6454
|
-
if (exception) {
|
|
6455
|
-
try {
|
|
6456
|
-
// @ts-ignore Object could be undefined
|
|
6457
|
-
return exception.values[0].stacktrace.frames;
|
|
6458
|
-
}
|
|
6459
|
-
catch (_oO) {
|
|
6460
|
-
return undefined;
|
|
6461
|
-
}
|
|
6462
|
-
}
|
|
6463
|
-
else if (event.stacktrace) {
|
|
6464
|
-
return event.stacktrace.frames;
|
|
6465
|
-
}
|
|
6466
|
-
return undefined;
|
|
6254
|
+
if (_isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6255
|
+
return true;
|
|
6467
6256
|
}
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6257
|
+
return false;
|
|
6258
|
+
}
|
|
6259
|
+
/** JSDoc */
|
|
6260
|
+
function _isSameMessageEvent(currentEvent, previousEvent) {
|
|
6261
|
+
const currentMessage = currentEvent.message;
|
|
6262
|
+
const previousMessage = previousEvent.message;
|
|
6263
|
+
// If neither event has a message property, they were both exceptions, so bail out
|
|
6264
|
+
if (!currentMessage && !previousMessage) {
|
|
6265
|
+
return false;
|
|
6266
|
+
}
|
|
6267
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6268
|
+
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6269
|
+
return false;
|
|
6270
|
+
}
|
|
6271
|
+
if (currentMessage !== previousMessage) {
|
|
6272
|
+
return false;
|
|
6273
|
+
}
|
|
6274
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6275
|
+
return false;
|
|
6276
|
+
}
|
|
6277
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6278
|
+
return false;
|
|
6279
|
+
}
|
|
6280
|
+
return true;
|
|
6281
|
+
}
|
|
6282
|
+
/** JSDoc */
|
|
6283
|
+
function _isSameExceptionEvent(currentEvent, previousEvent) {
|
|
6284
|
+
const previousException = _getExceptionFromEvent(previousEvent);
|
|
6285
|
+
const currentException = _getExceptionFromEvent(currentEvent);
|
|
6286
|
+
if (!previousException || !currentException) {
|
|
6287
|
+
return false;
|
|
6288
|
+
}
|
|
6289
|
+
if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
|
|
6290
|
+
return false;
|
|
6291
|
+
}
|
|
6292
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6293
|
+
return false;
|
|
6294
|
+
}
|
|
6295
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6296
|
+
return false;
|
|
6297
|
+
}
|
|
6298
|
+
return true;
|
|
6299
|
+
}
|
|
6300
|
+
/** JSDoc */
|
|
6301
|
+
function _isSameStacktrace(currentEvent, previousEvent) {
|
|
6302
|
+
let currentFrames = _getFramesFromEvent(currentEvent);
|
|
6303
|
+
let previousFrames = _getFramesFromEvent(previousEvent);
|
|
6304
|
+
// If neither event has a stacktrace, they are assumed to be the same
|
|
6305
|
+
if (!currentFrames && !previousFrames) {
|
|
6497
6306
|
return true;
|
|
6498
6307
|
}
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
return
|
|
6308
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6309
|
+
if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
|
|
6310
|
+
return false;
|
|
6502
6311
|
}
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
if (
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6312
|
+
currentFrames = currentFrames;
|
|
6313
|
+
previousFrames = previousFrames;
|
|
6314
|
+
// If number of frames differ, they are not the same
|
|
6315
|
+
if (previousFrames.length !== currentFrames.length) {
|
|
6316
|
+
return false;
|
|
6317
|
+
}
|
|
6318
|
+
// Otherwise, compare the two
|
|
6319
|
+
for (let i = 0; i < previousFrames.length; i++) {
|
|
6320
|
+
const frameA = previousFrames[i];
|
|
6321
|
+
const frameB = currentFrames[i];
|
|
6322
|
+
if (frameA.filename !== frameB.filename ||
|
|
6323
|
+
frameA.lineno !== frameB.lineno ||
|
|
6324
|
+
frameA.colno !== frameB.colno ||
|
|
6325
|
+
frameA.function !== frameB.function) {
|
|
6517
6326
|
return false;
|
|
6518
6327
|
}
|
|
6328
|
+
}
|
|
6329
|
+
return true;
|
|
6330
|
+
}
|
|
6331
|
+
/** JSDoc */
|
|
6332
|
+
function _isSameFingerprint(currentEvent, previousEvent) {
|
|
6333
|
+
let currentFingerprint = currentEvent.fingerprint;
|
|
6334
|
+
let previousFingerprint = previousEvent.fingerprint;
|
|
6335
|
+
// If neither event has a fingerprint, they are assumed to be the same
|
|
6336
|
+
if (!currentFingerprint && !previousFingerprint) {
|
|
6519
6337
|
return true;
|
|
6520
6338
|
}
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6339
|
+
// If only one event has a fingerprint, but not the other one, they are not the same
|
|
6340
|
+
if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
|
|
6341
|
+
return false;
|
|
6342
|
+
}
|
|
6343
|
+
currentFingerprint = currentFingerprint;
|
|
6344
|
+
previousFingerprint = previousFingerprint;
|
|
6345
|
+
// Otherwise, compare the two
|
|
6346
|
+
try {
|
|
6347
|
+
return !!(currentFingerprint.join('') === previousFingerprint.join(''));
|
|
6348
|
+
}
|
|
6349
|
+
catch (_oO) {
|
|
6350
|
+
return false;
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6353
|
+
/** JSDoc */
|
|
6354
|
+
function _getExceptionFromEvent(event) {
|
|
6355
|
+
return event.exception && event.exception.values && event.exception.values[0];
|
|
6356
|
+
}
|
|
6357
|
+
/** JSDoc */
|
|
6358
|
+
function _getFramesFromEvent(event) {
|
|
6359
|
+
const exception = event.exception;
|
|
6360
|
+
if (exception) {
|
|
6536
6361
|
try {
|
|
6537
|
-
|
|
6362
|
+
// @ts-ignore Object could be undefined
|
|
6363
|
+
return exception.values[0].stacktrace.frames;
|
|
6538
6364
|
}
|
|
6539
6365
|
catch (_oO) {
|
|
6540
|
-
return
|
|
6366
|
+
return undefined;
|
|
6541
6367
|
}
|
|
6542
6368
|
}
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6369
|
+
else if (event.stacktrace) {
|
|
6370
|
+
return event.stacktrace.frames;
|
|
6371
|
+
}
|
|
6372
|
+
return undefined;
|
|
6373
|
+
}
|
|
6548
6374
|
|
|
6549
6375
|
|
|
6550
6376
|
|
|
@@ -6763,8 +6589,10 @@ var Sentry = (function (exports) {
|
|
|
6763
6589
|
if (client) {
|
|
6764
6590
|
return client.flush(timeout);
|
|
6765
6591
|
}
|
|
6766
|
-
|
|
6767
|
-
|
|
6592
|
+
if (isDebugBuild()) {
|
|
6593
|
+
logger.warn('Cannot flush events. No client defined.');
|
|
6594
|
+
}
|
|
6595
|
+
return resolvedSyncPromise(false);
|
|
6768
6596
|
}
|
|
6769
6597
|
/**
|
|
6770
6598
|
* Call `close()` on the current client, if there is one. See {@link Client.close}.
|
|
@@ -6779,8 +6607,10 @@ var Sentry = (function (exports) {
|
|
|
6779
6607
|
if (client) {
|
|
6780
6608
|
return client.close(timeout);
|
|
6781
6609
|
}
|
|
6782
|
-
|
|
6783
|
-
|
|
6610
|
+
if (isDebugBuild()) {
|
|
6611
|
+
logger.warn('Cannot flush events and disable SDK. No client defined.');
|
|
6612
|
+
}
|
|
6613
|
+
return resolvedSyncPromise(false);
|
|
6784
6614
|
}
|
|
6785
6615
|
/**
|
|
6786
6616
|
* Wrap code within a try/catch block so the SDK is able to capture errors.
|
|
@@ -6793,6 +6623,10 @@ var Sentry = (function (exports) {
|
|
|
6793
6623
|
function wrap$1(fn) {
|
|
6794
6624
|
return wrap(fn)();
|
|
6795
6625
|
}
|
|
6626
|
+
function startSessionOnHub(hub) {
|
|
6627
|
+
hub.startSession({ ignoreDuration: true });
|
|
6628
|
+
hub.captureSession();
|
|
6629
|
+
}
|
|
6796
6630
|
/**
|
|
6797
6631
|
* Enable automatic Session Tracking for the initial page load.
|
|
6798
6632
|
*/
|
|
@@ -6800,7 +6634,9 @@ var Sentry = (function (exports) {
|
|
|
6800
6634
|
const window = getGlobalObject();
|
|
6801
6635
|
const document = window.document;
|
|
6802
6636
|
if (typeof document === 'undefined') {
|
|
6803
|
-
|
|
6637
|
+
if (isDebugBuild()) {
|
|
6638
|
+
logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
|
|
6639
|
+
}
|
|
6804
6640
|
return;
|
|
6805
6641
|
}
|
|
6806
6642
|
const hub = getCurrentHub();
|
|
@@ -6810,26 +6646,20 @@ var Sentry = (function (exports) {
|
|
|
6810
6646
|
// https://github.com/getsentry/sentry-javascript/issues/3207 and
|
|
6811
6647
|
// https://github.com/getsentry/sentry-javascript/issues/3234 and
|
|
6812
6648
|
// https://github.com/getsentry/sentry-javascript/issues/3278.
|
|
6813
|
-
if (
|
|
6649
|
+
if (!hub.captureSession) {
|
|
6814
6650
|
return;
|
|
6815
6651
|
}
|
|
6816
6652
|
// The session duration for browser sessions does not track a meaningful
|
|
6817
6653
|
// concept that can be used as a metric.
|
|
6818
6654
|
// Automatically captured sessions are akin to page views, and thus we
|
|
6819
6655
|
// discard their duration.
|
|
6820
|
-
hub
|
|
6821
|
-
hub.captureSession();
|
|
6656
|
+
startSessionOnHub(hub);
|
|
6822
6657
|
// We want to create a session for every navigation as well
|
|
6823
|
-
addInstrumentationHandler({
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
}
|
|
6829
|
-
hub.startSession({ ignoreDuration: true });
|
|
6830
|
-
hub.captureSession();
|
|
6831
|
-
},
|
|
6832
|
-
type: 'history',
|
|
6658
|
+
addInstrumentationHandler('history', ({ from, to }) => {
|
|
6659
|
+
// Don't create an additional session for the initial route or if the location did not change
|
|
6660
|
+
if (!(from === undefined || from === to)) {
|
|
6661
|
+
startSessionOnHub(getCurrentHub());
|
|
6662
|
+
}
|
|
6833
6663
|
});
|
|
6834
6664
|
}
|
|
6835
6665
|
|