@sentry/browser 6.14.3 → 6.17.0-beta.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 +1271 -1393
- 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 +1367 -1520
- package/build/bundle.js.map +1 -1
- package/build/bundle.min.js +2 -2
- package/build/bundle.min.js.map +1 -1
- package/dist/backend.d.ts +2 -2
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +1 -2
- package/dist/backend.js.map +1 -1
- package/dist/eventbuilder.d.ts +2 -2
- package/dist/eventbuilder.d.ts.map +1 -1
- package/dist/eventbuilder.js +20 -13
- 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 -3
- 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 -174
- 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 -169
- 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 +3 -17
- 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/backend.d.ts +2 -2
- package/esm/backend.d.ts.map +1 -1
- package/esm/backend.js +1 -2
- package/esm/backend.js.map +1 -1
- package/esm/eventbuilder.d.ts +2 -2
- package/esm/eventbuilder.d.ts.map +1 -1
- package/esm/eventbuilder.js +21 -14
- 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 +0 -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 -176
- 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 -171
- 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 +3 -17
- 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,149 +1,5 @@
|
|
|
1
|
-
/*! @sentry/browser 6.
|
|
1
|
+
/*! @sentry/browser 6.17.0-beta.0 (2a9a3d4) | 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
|
-
/**
|
|
17
|
-
* Session Status
|
|
18
|
-
*/
|
|
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
|
-
(function (Severity) {
|
|
42
|
-
/** JSDoc */
|
|
43
|
-
Severity["Fatal"] = "fatal";
|
|
44
|
-
/** JSDoc */
|
|
45
|
-
Severity["Error"] = "error";
|
|
46
|
-
/** JSDoc */
|
|
47
|
-
Severity["Warning"] = "warning";
|
|
48
|
-
/** JSDoc */
|
|
49
|
-
Severity["Log"] = "log";
|
|
50
|
-
/** JSDoc */
|
|
51
|
-
Severity["Info"] = "info";
|
|
52
|
-
/** JSDoc */
|
|
53
|
-
Severity["Debug"] = "debug";
|
|
54
|
-
/** JSDoc */
|
|
55
|
-
Severity["Critical"] = "critical";
|
|
56
|
-
})(exports.Severity || (exports.Severity = {}));
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace, import/export
|
|
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 = {}));
|
|
146
|
-
|
|
147
3
|
/**
|
|
148
4
|
* Consumes the promise and logs the error when it rejects.
|
|
149
5
|
* @param promise A promise to forget.
|
|
@@ -157,6 +13,33 @@ var Sentry = (function (exports) {
|
|
|
157
13
|
});
|
|
158
14
|
}
|
|
159
15
|
|
|
16
|
+
/**
|
|
17
|
+
* This module mostly exists for optimizations in the build process
|
|
18
|
+
* through rollup and terser. We define some global constants which
|
|
19
|
+
* are normally undefined. However terser overrides these with global
|
|
20
|
+
* definitions which can be evaluated by the static analyzer when
|
|
21
|
+
* creating a bundle.
|
|
22
|
+
*
|
|
23
|
+
* In turn the `isDebugBuild` and `isBrowserBundle` functions are pure
|
|
24
|
+
* and can help us remove unused code from the bundles.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Figures out if we're building with debug functionality.
|
|
28
|
+
*
|
|
29
|
+
* @returns true if this is a debug build
|
|
30
|
+
*/
|
|
31
|
+
function isDebugBuild() {
|
|
32
|
+
return typeof __SENTRY_NO_DEBUG__ !== 'undefined' && !__SENTRY_BROWSER_BUNDLE__;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Figures out if we're building a browser bundle.
|
|
36
|
+
*
|
|
37
|
+
* @returns true if this is a browser bundle build.
|
|
38
|
+
*/
|
|
39
|
+
function isBrowserBundle() {
|
|
40
|
+
return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
|
|
41
|
+
}
|
|
42
|
+
|
|
160
43
|
/**
|
|
161
44
|
* NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
|
|
162
45
|
* you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
|
|
@@ -167,7 +50,10 @@ var Sentry = (function (exports) {
|
|
|
167
50
|
* @returns Answer to given question
|
|
168
51
|
*/
|
|
169
52
|
function isNodeEnv() {
|
|
170
|
-
|
|
53
|
+
// explicitly check for browser bundles as those can be optimized statically
|
|
54
|
+
// by terser/rollup.
|
|
55
|
+
return (!isBrowserBundle() &&
|
|
56
|
+
Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]');
|
|
171
57
|
}
|
|
172
58
|
/**
|
|
173
59
|
* Requires a module which is protected against bundler minification.
|
|
@@ -202,6 +88,8 @@ var Sentry = (function (exports) {
|
|
|
202
88
|
|
|
203
89
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
204
90
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
92
|
+
const objectToString = Object.prototype.toString;
|
|
205
93
|
/**
|
|
206
94
|
* Checks whether given value's type is one of a few Error or Error-like
|
|
207
95
|
* {@link isError}.
|
|
@@ -210,17 +98,18 @@ var Sentry = (function (exports) {
|
|
|
210
98
|
* @returns A boolean representing the result.
|
|
211
99
|
*/
|
|
212
100
|
function isError(wat) {
|
|
213
|
-
switch (
|
|
101
|
+
switch (objectToString.call(wat)) {
|
|
214
102
|
case '[object Error]':
|
|
215
|
-
return true;
|
|
216
103
|
case '[object Exception]':
|
|
217
|
-
return true;
|
|
218
104
|
case '[object DOMException]':
|
|
219
105
|
return true;
|
|
220
106
|
default:
|
|
221
107
|
return isInstanceOf(wat, Error);
|
|
222
108
|
}
|
|
223
109
|
}
|
|
110
|
+
function isBuiltin(wat, ty) {
|
|
111
|
+
return objectToString.call(wat) === `[object ${ty}]`;
|
|
112
|
+
}
|
|
224
113
|
/**
|
|
225
114
|
* Checks whether given value's type is ErrorEvent
|
|
226
115
|
* {@link isErrorEvent}.
|
|
@@ -229,7 +118,7 @@ var Sentry = (function (exports) {
|
|
|
229
118
|
* @returns A boolean representing the result.
|
|
230
119
|
*/
|
|
231
120
|
function isErrorEvent(wat) {
|
|
232
|
-
return
|
|
121
|
+
return isBuiltin(wat, 'ErrorEvent');
|
|
233
122
|
}
|
|
234
123
|
/**
|
|
235
124
|
* Checks whether given value's type is DOMError
|
|
@@ -239,7 +128,7 @@ var Sentry = (function (exports) {
|
|
|
239
128
|
* @returns A boolean representing the result.
|
|
240
129
|
*/
|
|
241
130
|
function isDOMError(wat) {
|
|
242
|
-
return
|
|
131
|
+
return isBuiltin(wat, 'DOMError');
|
|
243
132
|
}
|
|
244
133
|
/**
|
|
245
134
|
* Checks whether given value's type is DOMException
|
|
@@ -249,7 +138,7 @@ var Sentry = (function (exports) {
|
|
|
249
138
|
* @returns A boolean representing the result.
|
|
250
139
|
*/
|
|
251
140
|
function isDOMException(wat) {
|
|
252
|
-
return
|
|
141
|
+
return isBuiltin(wat, 'DOMException');
|
|
253
142
|
}
|
|
254
143
|
/**
|
|
255
144
|
* Checks whether given value's type is a string
|
|
@@ -259,7 +148,7 @@ var Sentry = (function (exports) {
|
|
|
259
148
|
* @returns A boolean representing the result.
|
|
260
149
|
*/
|
|
261
150
|
function isString(wat) {
|
|
262
|
-
return
|
|
151
|
+
return isBuiltin(wat, 'String');
|
|
263
152
|
}
|
|
264
153
|
/**
|
|
265
154
|
* Checks whether given value's is a primitive (undefined, null, number, boolean, string, bigint, symbol)
|
|
@@ -279,7 +168,7 @@ var Sentry = (function (exports) {
|
|
|
279
168
|
* @returns A boolean representing the result.
|
|
280
169
|
*/
|
|
281
170
|
function isPlainObject(wat) {
|
|
282
|
-
return
|
|
171
|
+
return isBuiltin(wat, 'Object');
|
|
283
172
|
}
|
|
284
173
|
/**
|
|
285
174
|
* Checks whether given value's type is an Event instance
|
|
@@ -309,7 +198,7 @@ var Sentry = (function (exports) {
|
|
|
309
198
|
* @returns A boolean representing the result.
|
|
310
199
|
*/
|
|
311
200
|
function isRegExp(wat) {
|
|
312
|
-
return
|
|
201
|
+
return isBuiltin(wat, 'RegExp');
|
|
313
202
|
}
|
|
314
203
|
/**
|
|
315
204
|
* Checks whether given value has a then function.
|
|
@@ -393,7 +282,6 @@ var Sentry = (function (exports) {
|
|
|
393
282
|
* @returns generated DOM path
|
|
394
283
|
*/
|
|
395
284
|
function _htmlElementAsString(el, keyAttrs) {
|
|
396
|
-
var _a, _b;
|
|
397
285
|
const elem = el;
|
|
398
286
|
const out = [];
|
|
399
287
|
let className;
|
|
@@ -406,9 +294,10 @@ var Sentry = (function (exports) {
|
|
|
406
294
|
}
|
|
407
295
|
out.push(elem.tagName.toLowerCase());
|
|
408
296
|
// Pairs of attribute keys defined in `serializeAttribute` and their values on element.
|
|
409
|
-
const keyAttrPairs =
|
|
297
|
+
const keyAttrPairs = keyAttrs && keyAttrs.length
|
|
298
|
+
? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
|
|
410
299
|
: null;
|
|
411
|
-
if (
|
|
300
|
+
if (keyAttrPairs && keyAttrPairs.length) {
|
|
412
301
|
keyAttrPairs.forEach(keyAttrPair => {
|
|
413
302
|
out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
|
|
414
303
|
});
|
|
@@ -485,88 +374,87 @@ var Sentry = (function (exports) {
|
|
|
485
374
|
|
|
486
375
|
/** Regular expression used to parse a Dsn. */
|
|
487
376
|
const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
377
|
+
function isValidProtocol(protocol) {
|
|
378
|
+
return protocol === 'http' || protocol === 'https';
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Renders the string representation of this Dsn.
|
|
382
|
+
*
|
|
383
|
+
* By default, this will render the public representation without the password
|
|
384
|
+
* component. To get the deprecated private representation, set `withPassword`
|
|
385
|
+
* to true.
|
|
386
|
+
*
|
|
387
|
+
* @param withPassword When set to true, the password will be included.
|
|
388
|
+
*/
|
|
389
|
+
function dsnToString(dsn, withPassword = false) {
|
|
390
|
+
const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
|
|
391
|
+
return (`${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
|
|
392
|
+
`@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`);
|
|
393
|
+
}
|
|
394
|
+
function dsnFromString(str) {
|
|
395
|
+
const match = DSN_REGEX.exec(str);
|
|
396
|
+
if (!match) {
|
|
397
|
+
throw new SentryError('Invalid Dsn');
|
|
501
398
|
}
|
|
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}`);
|
|
399
|
+
const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
|
|
400
|
+
let path = '';
|
|
401
|
+
let projectId = lastPath;
|
|
402
|
+
const split = projectId.split('/');
|
|
403
|
+
if (split.length > 1) {
|
|
404
|
+
path = split.slice(0, -1).join('/');
|
|
405
|
+
projectId = split.pop();
|
|
406
|
+
}
|
|
407
|
+
if (projectId) {
|
|
408
|
+
const projectMatch = projectId.match(/^\d+/);
|
|
409
|
+
if (projectMatch) {
|
|
410
|
+
projectId = projectMatch[0];
|
|
565
411
|
}
|
|
566
|
-
|
|
567
|
-
|
|
412
|
+
}
|
|
413
|
+
return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
|
|
414
|
+
}
|
|
415
|
+
function dsnFromComponents(components) {
|
|
416
|
+
// TODO this is for backwards compatibility, and can be removed in a future version
|
|
417
|
+
if ('user' in components && !('publicKey' in components)) {
|
|
418
|
+
components.publicKey = components.user;
|
|
419
|
+
}
|
|
420
|
+
return {
|
|
421
|
+
user: components.publicKey || '',
|
|
422
|
+
protocol: components.protocol,
|
|
423
|
+
publicKey: components.publicKey || '',
|
|
424
|
+
pass: components.pass || '',
|
|
425
|
+
host: components.host,
|
|
426
|
+
port: components.port || '',
|
|
427
|
+
path: components.path || '',
|
|
428
|
+
projectId: components.projectId,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function validateDsn(dsn) {
|
|
432
|
+
if (!isDebugBuild()) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const { port, projectId, protocol } = dsn;
|
|
436
|
+
const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];
|
|
437
|
+
requiredComponents.forEach(component => {
|
|
438
|
+
if (!dsn[component]) {
|
|
439
|
+
throw new SentryError(`Invalid Dsn: ${component} missing`);
|
|
568
440
|
}
|
|
441
|
+
});
|
|
442
|
+
if (!projectId.match(/^\d+$/)) {
|
|
443
|
+
throw new SentryError(`Invalid Dsn: Invalid projectId ${projectId}`);
|
|
569
444
|
}
|
|
445
|
+
if (!isValidProtocol(protocol)) {
|
|
446
|
+
throw new SentryError(`Invalid Dsn: Invalid protocol ${protocol}`);
|
|
447
|
+
}
|
|
448
|
+
if (port && isNaN(parseInt(port, 10))) {
|
|
449
|
+
throw new SentryError(`Invalid Dsn: Invalid port ${port}`);
|
|
450
|
+
}
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
/** The Sentry Dsn, identifying a Sentry instance and project. */
|
|
454
|
+
function makeDsn(from) {
|
|
455
|
+
const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
|
|
456
|
+
validateDsn(components);
|
|
457
|
+
return components;
|
|
570
458
|
}
|
|
571
459
|
|
|
572
460
|
// TODO: Implement different loggers for different environments
|
|
@@ -653,54 +541,44 @@ var Sentry = (function (exports) {
|
|
|
653
541
|
|
|
654
542
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
655
543
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
656
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
657
544
|
/**
|
|
658
|
-
*
|
|
545
|
+
* Helper to decycle json objects
|
|
659
546
|
*/
|
|
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)) {
|
|
547
|
+
function memoBuilder() {
|
|
548
|
+
const hasWeakSet = typeof WeakSet === 'function';
|
|
549
|
+
const inner = hasWeakSet ? new WeakSet() : [];
|
|
550
|
+
function memoize(obj) {
|
|
551
|
+
if (hasWeakSet) {
|
|
552
|
+
if (inner.has(obj)) {
|
|
672
553
|
return true;
|
|
673
554
|
}
|
|
674
|
-
|
|
555
|
+
inner.add(obj);
|
|
675
556
|
return false;
|
|
676
557
|
}
|
|
677
558
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
678
|
-
for (let i = 0; i <
|
|
679
|
-
const value =
|
|
559
|
+
for (let i = 0; i < inner.length; i++) {
|
|
560
|
+
const value = inner[i];
|
|
680
561
|
if (value === obj) {
|
|
681
562
|
return true;
|
|
682
563
|
}
|
|
683
564
|
}
|
|
684
|
-
|
|
565
|
+
inner.push(obj);
|
|
685
566
|
return false;
|
|
686
567
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
*/
|
|
691
|
-
unmemoize(obj) {
|
|
692
|
-
if (this._hasWeakSet) {
|
|
693
|
-
this._inner.delete(obj);
|
|
568
|
+
function unmemoize(obj) {
|
|
569
|
+
if (hasWeakSet) {
|
|
570
|
+
inner.delete(obj);
|
|
694
571
|
}
|
|
695
572
|
else {
|
|
696
|
-
for (let i = 0; i <
|
|
697
|
-
if (
|
|
698
|
-
|
|
573
|
+
for (let i = 0; i < inner.length; i++) {
|
|
574
|
+
if (inner[i] === obj) {
|
|
575
|
+
inner.splice(i, 1);
|
|
699
576
|
break;
|
|
700
577
|
}
|
|
701
578
|
}
|
|
702
579
|
}
|
|
703
580
|
}
|
|
581
|
+
return [memoize, unmemoize];
|
|
704
582
|
}
|
|
705
583
|
|
|
706
584
|
const defaultFunctionName = '<anonymous>';
|
|
@@ -797,13 +675,7 @@ var Sentry = (function (exports) {
|
|
|
797
675
|
// otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
|
|
798
676
|
if (typeof wrapped === 'function') {
|
|
799
677
|
try {
|
|
800
|
-
wrapped
|
|
801
|
-
Object.defineProperties(wrapped, {
|
|
802
|
-
__sentry_original__: {
|
|
803
|
-
enumerable: false,
|
|
804
|
-
value: original,
|
|
805
|
-
},
|
|
806
|
-
});
|
|
678
|
+
markFunctionWrapped(wrapped, original);
|
|
807
679
|
}
|
|
808
680
|
catch (_Oo) {
|
|
809
681
|
// This can throw if multiple fill happens on a global object like XMLHttpRequest
|
|
@@ -812,6 +684,41 @@ var Sentry = (function (exports) {
|
|
|
812
684
|
}
|
|
813
685
|
source[name] = wrapped;
|
|
814
686
|
}
|
|
687
|
+
/**
|
|
688
|
+
* Defines a non enumerable property. This creates a non enumerable property on an object.
|
|
689
|
+
*
|
|
690
|
+
* @param func The function to set a property to
|
|
691
|
+
* @param name the name of the special sentry property
|
|
692
|
+
* @param value the property to define
|
|
693
|
+
*/
|
|
694
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
695
|
+
function addNonEnumerableProperty(func, name, value) {
|
|
696
|
+
Object.defineProperty(func, name, {
|
|
697
|
+
value: value,
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Remembers the original function on the wrapped function and
|
|
702
|
+
* patches up the prototype.
|
|
703
|
+
*
|
|
704
|
+
* @param wrapped the wrapper function
|
|
705
|
+
* @param original the original function that gets wrapped
|
|
706
|
+
*/
|
|
707
|
+
function markFunctionWrapped(wrapped, original) {
|
|
708
|
+
const proto = original.prototype || {};
|
|
709
|
+
wrapped.prototype = original.prototype = proto;
|
|
710
|
+
addNonEnumerableProperty(wrapped, '__sentry_original__', original);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* This extracts the original function if available. See
|
|
714
|
+
* `markFunctionWrapped` for more information.
|
|
715
|
+
*
|
|
716
|
+
* @param func the function to unwrap
|
|
717
|
+
* @returns the unwrapped version of the function if available.
|
|
718
|
+
*/
|
|
719
|
+
function getOriginalFunction(func) {
|
|
720
|
+
return func.__sentry_original__;
|
|
721
|
+
}
|
|
815
722
|
/**
|
|
816
723
|
* Encodes given object into url-friendly format
|
|
817
724
|
*
|
|
@@ -910,11 +817,11 @@ var Sentry = (function (exports) {
|
|
|
910
817
|
* unchanged.
|
|
911
818
|
*/
|
|
912
819
|
function serializeValue(value) {
|
|
913
|
-
const type = Object.prototype.toString.call(value);
|
|
914
820
|
// Node.js REPL notation
|
|
915
821
|
if (typeof value === 'string') {
|
|
916
822
|
return value;
|
|
917
823
|
}
|
|
824
|
+
const type = Object.prototype.toString.call(value);
|
|
918
825
|
if (type === '[object Object]') {
|
|
919
826
|
return '[Object]';
|
|
920
827
|
}
|
|
@@ -984,7 +891,7 @@ var Sentry = (function (exports) {
|
|
|
984
891
|
* @param memo Optional Memo class handling decycling
|
|
985
892
|
*/
|
|
986
893
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
987
|
-
function walk(key, value, depth = +Infinity, memo =
|
|
894
|
+
function walk(key, value, depth = +Infinity, memo = memoBuilder()) {
|
|
988
895
|
// If we reach the maximum depth, serialize whatever has left
|
|
989
896
|
if (depth === 0) {
|
|
990
897
|
return serializeValue(value);
|
|
@@ -1005,7 +912,7 @@ var Sentry = (function (exports) {
|
|
|
1005
912
|
// Create an accumulator that will act as a parent for all future itterations of that branch
|
|
1006
913
|
const acc = Array.isArray(value) ? [] : {};
|
|
1007
914
|
// If we already walked that branch, bail out, as it's circular reference
|
|
1008
|
-
if (memo
|
|
915
|
+
if (memo[0](value)) {
|
|
1009
916
|
return '[Circular ~]';
|
|
1010
917
|
}
|
|
1011
918
|
// Walk all keys of the source
|
|
@@ -1018,7 +925,7 @@ var Sentry = (function (exports) {
|
|
|
1018
925
|
acc[innerKey] = walk(innerKey, source[innerKey], depth - 1, memo);
|
|
1019
926
|
}
|
|
1020
927
|
// Once walked through all the branches, remove the parent from memo storage
|
|
1021
|
-
memo
|
|
928
|
+
memo[1](value);
|
|
1022
929
|
// Return accumulated values
|
|
1023
930
|
return acc;
|
|
1024
931
|
}
|
|
@@ -1151,7 +1058,9 @@ var Sentry = (function (exports) {
|
|
|
1151
1058
|
doc.head.removeChild(sandbox);
|
|
1152
1059
|
}
|
|
1153
1060
|
catch (err) {
|
|
1154
|
-
|
|
1061
|
+
if (isDebugBuild()) {
|
|
1062
|
+
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
|
|
1063
|
+
}
|
|
1155
1064
|
}
|
|
1156
1065
|
}
|
|
1157
1066
|
return result;
|
|
@@ -1250,13 +1159,10 @@ var Sentry = (function (exports) {
|
|
|
1250
1159
|
* Use at your own risk, this might break without changelog notice, only used internally.
|
|
1251
1160
|
* @hidden
|
|
1252
1161
|
*/
|
|
1253
|
-
function addInstrumentationHandler(
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
handlers[handler.type] = handlers[handler.type] || [];
|
|
1258
|
-
handlers[handler.type].push(handler.callback);
|
|
1259
|
-
instrument(handler.type);
|
|
1162
|
+
function addInstrumentationHandler(type, callback) {
|
|
1163
|
+
handlers[type] = handlers[type] || [];
|
|
1164
|
+
handlers[type].push(callback);
|
|
1165
|
+
instrument(type);
|
|
1260
1166
|
}
|
|
1261
1167
|
/** JSDoc */
|
|
1262
1168
|
function triggerHandlers(type, data) {
|
|
@@ -1268,7 +1174,9 @@ var Sentry = (function (exports) {
|
|
|
1268
1174
|
handler(data);
|
|
1269
1175
|
}
|
|
1270
1176
|
catch (e) {
|
|
1271
|
-
|
|
1177
|
+
if (isDebugBuild()) {
|
|
1178
|
+
logger.error(`Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError: ${e}`);
|
|
1179
|
+
}
|
|
1272
1180
|
}
|
|
1273
1181
|
}
|
|
1274
1182
|
}
|
|
@@ -1358,14 +1266,14 @@ var Sentry = (function (exports) {
|
|
|
1358
1266
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1359
1267
|
const xhr = this;
|
|
1360
1268
|
const url = args[1];
|
|
1361
|
-
xhr.__sentry_xhr__ = {
|
|
1269
|
+
const xhrInfo = (xhr.__sentry_xhr__ = {
|
|
1362
1270
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1363
1271
|
method: isString(args[0]) ? args[0].toUpperCase() : args[0],
|
|
1364
1272
|
url: args[1],
|
|
1365
|
-
};
|
|
1273
|
+
});
|
|
1366
1274
|
// if Sentry key appears in URL, don't capture it as a request
|
|
1367
1275
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1368
|
-
if (isString(url) &&
|
|
1276
|
+
if (isString(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) {
|
|
1369
1277
|
xhr.__sentry_own_request__ = true;
|
|
1370
1278
|
}
|
|
1371
1279
|
const onreadystatechangeHandler = function () {
|
|
@@ -1373,9 +1281,7 @@ var Sentry = (function (exports) {
|
|
|
1373
1281
|
try {
|
|
1374
1282
|
// touching statusCode in some platforms throws
|
|
1375
1283
|
// an exception
|
|
1376
|
-
|
|
1377
|
-
xhr.__sentry_xhr__.status_code = xhr.status;
|
|
1378
|
-
}
|
|
1284
|
+
xhrInfo.status_code = xhr.status;
|
|
1379
1285
|
}
|
|
1380
1286
|
catch (e) {
|
|
1381
1287
|
/* do nothing */
|
|
@@ -1386,8 +1292,8 @@ var Sentry = (function (exports) {
|
|
|
1386
1292
|
// Make sure to pop both key and value to keep it in sync.
|
|
1387
1293
|
requestKeys.splice(requestPos);
|
|
1388
1294
|
const args = requestValues.splice(requestPos)[0];
|
|
1389
|
-
if (
|
|
1390
|
-
|
|
1295
|
+
if (args[0] !== undefined) {
|
|
1296
|
+
xhrInfo.body = args[0];
|
|
1391
1297
|
}
|
|
1392
1298
|
}
|
|
1393
1299
|
}
|
|
@@ -1754,22 +1660,26 @@ var Sentry = (function (exports) {
|
|
|
1754
1660
|
relative: match[5] + query + fragment,
|
|
1755
1661
|
};
|
|
1756
1662
|
}
|
|
1663
|
+
function getFirstException(event) {
|
|
1664
|
+
return event.exception && event.exception.values ? event.exception.values[0] : undefined;
|
|
1665
|
+
}
|
|
1757
1666
|
/**
|
|
1758
1667
|
* Extracts either message or type+value from an event that can be used for user-facing logs
|
|
1759
1668
|
* @returns event's description
|
|
1760
1669
|
*/
|
|
1761
1670
|
function getEventDescription(event) {
|
|
1762
|
-
|
|
1763
|
-
|
|
1671
|
+
const { message, event_id: eventId } = event;
|
|
1672
|
+
if (message) {
|
|
1673
|
+
return message;
|
|
1764
1674
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
if (
|
|
1768
|
-
return `${
|
|
1675
|
+
const firstException = getFirstException(event);
|
|
1676
|
+
if (firstException) {
|
|
1677
|
+
if (firstException.type && firstException.value) {
|
|
1678
|
+
return `${firstException.type}: ${firstException.value}`;
|
|
1769
1679
|
}
|
|
1770
|
-
return
|
|
1680
|
+
return firstException.type || firstException.value || eventId || '<unknown>';
|
|
1771
1681
|
}
|
|
1772
|
-
return
|
|
1682
|
+
return eventId || '<unknown>';
|
|
1773
1683
|
}
|
|
1774
1684
|
/**
|
|
1775
1685
|
* Adds exception values, type and value to an synthetic Exception.
|
|
@@ -1779,11 +1689,15 @@ var Sentry = (function (exports) {
|
|
|
1779
1689
|
* @hidden
|
|
1780
1690
|
*/
|
|
1781
1691
|
function addExceptionTypeValue(event, value, type) {
|
|
1782
|
-
event.exception = event.exception || {};
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1692
|
+
const exception = (event.exception = event.exception || {});
|
|
1693
|
+
const values = (exception.values = exception.values || []);
|
|
1694
|
+
const firstException = (values[0] = values[0] || {});
|
|
1695
|
+
if (!firstException.value) {
|
|
1696
|
+
firstException.value = value || '';
|
|
1697
|
+
}
|
|
1698
|
+
if (!firstException.type) {
|
|
1699
|
+
firstException.type = type || 'Error';
|
|
1700
|
+
}
|
|
1787
1701
|
}
|
|
1788
1702
|
/**
|
|
1789
1703
|
* Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
|
|
@@ -1793,17 +1707,16 @@ var Sentry = (function (exports) {
|
|
|
1793
1707
|
* @hidden
|
|
1794
1708
|
*/
|
|
1795
1709
|
function addExceptionMechanism(event, newMechanism) {
|
|
1796
|
-
|
|
1797
|
-
if (!
|
|
1710
|
+
const firstException = getFirstException(event);
|
|
1711
|
+
if (!firstException) {
|
|
1798
1712
|
return;
|
|
1799
1713
|
}
|
|
1800
|
-
const exceptionValue0 = event.exception.values[0];
|
|
1801
1714
|
const defaultMechanism = { type: 'generic', handled: true };
|
|
1802
|
-
const currentMechanism =
|
|
1803
|
-
|
|
1715
|
+
const currentMechanism = firstException.mechanism;
|
|
1716
|
+
firstException.mechanism = Object.assign(Object.assign(Object.assign({}, defaultMechanism), currentMechanism), newMechanism);
|
|
1804
1717
|
if (newMechanism && 'data' in newMechanism) {
|
|
1805
|
-
const mergedData = Object.assign(Object.assign({}, (
|
|
1806
|
-
|
|
1718
|
+
const mergedData = Object.assign(Object.assign({}, (currentMechanism && currentMechanism.data)), newMechanism.data);
|
|
1719
|
+
firstException.mechanism.data = mergedData;
|
|
1807
1720
|
}
|
|
1808
1721
|
}
|
|
1809
1722
|
const defaultRetryAfter = 60 * 1000; // 60 seconds
|
|
@@ -1848,17 +1761,14 @@ var Sentry = (function (exports) {
|
|
|
1848
1761
|
* @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
|
|
1849
1762
|
*/
|
|
1850
1763
|
function checkOrSetAlreadyCaught(exception) {
|
|
1851
|
-
var _a;
|
|
1852
1764
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1853
|
-
if (
|
|
1765
|
+
if (exception && exception.__sentry_captured__) {
|
|
1854
1766
|
return true;
|
|
1855
1767
|
}
|
|
1856
1768
|
try {
|
|
1857
1769
|
// set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
|
|
1858
1770
|
// `ExtraErrorData` integration
|
|
1859
|
-
|
|
1860
|
-
value: true,
|
|
1861
|
-
});
|
|
1771
|
+
addNonEnumerableProperty(exception, '__sentry_captured__', true);
|
|
1862
1772
|
}
|
|
1863
1773
|
catch (err) {
|
|
1864
1774
|
// `exception` is a primitive, so we can't mark it seen
|
|
@@ -1867,35 +1777,47 @@ var Sentry = (function (exports) {
|
|
|
1867
1777
|
}
|
|
1868
1778
|
|
|
1869
1779
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1870
|
-
/**
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1780
|
+
/**
|
|
1781
|
+
* Creates a resolved sync promise.
|
|
1782
|
+
*
|
|
1783
|
+
* @param value the value to resolve the promise with
|
|
1784
|
+
* @returns the resolved sync promise
|
|
1785
|
+
*/
|
|
1786
|
+
function resolvedSyncPromise(value) {
|
|
1787
|
+
return new SyncPromise(resolve => {
|
|
1788
|
+
resolve(value);
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
/**
|
|
1792
|
+
* Creates a rejected sync promise.
|
|
1793
|
+
*
|
|
1794
|
+
* @param value the value to reject the promise with
|
|
1795
|
+
* @returns the rejected sync promise
|
|
1796
|
+
*/
|
|
1797
|
+
function rejectedSyncPromise(reason) {
|
|
1798
|
+
return new SyncPromise((_, reject) => {
|
|
1799
|
+
reject(reason);
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1880
1802
|
/**
|
|
1881
1803
|
* Thenable class that behaves like a Promise and follows it's interface
|
|
1882
1804
|
* but is not async internally
|
|
1883
1805
|
*/
|
|
1884
1806
|
class SyncPromise {
|
|
1885
1807
|
constructor(executor) {
|
|
1886
|
-
this._state =
|
|
1808
|
+
this._state = 0 /* PENDING */;
|
|
1887
1809
|
this._handlers = [];
|
|
1888
1810
|
/** JSDoc */
|
|
1889
1811
|
this._resolve = (value) => {
|
|
1890
|
-
this._setResult(
|
|
1812
|
+
this._setResult(1 /* RESOLVED */, value);
|
|
1891
1813
|
};
|
|
1892
1814
|
/** JSDoc */
|
|
1893
1815
|
this._reject = (reason) => {
|
|
1894
|
-
this._setResult(
|
|
1816
|
+
this._setResult(2 /* REJECTED */, reason);
|
|
1895
1817
|
};
|
|
1896
1818
|
/** JSDoc */
|
|
1897
1819
|
this._setResult = (state, value) => {
|
|
1898
|
-
if (this._state !==
|
|
1820
|
+
if (this._state !== 0 /* PENDING */) {
|
|
1899
1821
|
return;
|
|
1900
1822
|
}
|
|
1901
1823
|
if (isThenable(value)) {
|
|
@@ -1906,35 +1828,25 @@ var Sentry = (function (exports) {
|
|
|
1906
1828
|
this._value = value;
|
|
1907
1829
|
this._executeHandlers();
|
|
1908
1830
|
};
|
|
1909
|
-
// TODO: FIXME
|
|
1910
|
-
/** JSDoc */
|
|
1911
|
-
this._attachHandler = (handler) => {
|
|
1912
|
-
this._handlers = this._handlers.concat(handler);
|
|
1913
|
-
this._executeHandlers();
|
|
1914
|
-
};
|
|
1915
1831
|
/** JSDoc */
|
|
1916
1832
|
this._executeHandlers = () => {
|
|
1917
|
-
if (this._state ===
|
|
1833
|
+
if (this._state === 0 /* PENDING */) {
|
|
1918
1834
|
return;
|
|
1919
1835
|
}
|
|
1920
1836
|
const cachedHandlers = this._handlers.slice();
|
|
1921
1837
|
this._handlers = [];
|
|
1922
1838
|
cachedHandlers.forEach(handler => {
|
|
1923
|
-
if (handler
|
|
1839
|
+
if (handler[0]) {
|
|
1924
1840
|
return;
|
|
1925
1841
|
}
|
|
1926
|
-
if (this._state ===
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
handler.onfulfilled(this._value);
|
|
1930
|
-
}
|
|
1842
|
+
if (this._state === 1 /* RESOLVED */) {
|
|
1843
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1844
|
+
handler[1](this._value);
|
|
1931
1845
|
}
|
|
1932
|
-
if (this._state ===
|
|
1933
|
-
|
|
1934
|
-
handler.onrejected(this._value);
|
|
1935
|
-
}
|
|
1846
|
+
if (this._state === 2 /* REJECTED */) {
|
|
1847
|
+
handler[2](this._value);
|
|
1936
1848
|
}
|
|
1937
|
-
handler
|
|
1849
|
+
handler[0] = true;
|
|
1938
1850
|
});
|
|
1939
1851
|
};
|
|
1940
1852
|
try {
|
|
@@ -1945,80 +1857,40 @@ var Sentry = (function (exports) {
|
|
|
1945
1857
|
}
|
|
1946
1858
|
}
|
|
1947
1859
|
/** 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
1860
|
then(onfulfilled, onrejected) {
|
|
1988
1861
|
return new SyncPromise((resolve, reject) => {
|
|
1989
|
-
this.
|
|
1990
|
-
|
|
1991
|
-
|
|
1862
|
+
this._handlers.push([
|
|
1863
|
+
false,
|
|
1864
|
+
result => {
|
|
1992
1865
|
if (!onfulfilled) {
|
|
1993
1866
|
// TODO: ¯\_(ツ)_/¯
|
|
1994
1867
|
// TODO: FIXME
|
|
1995
1868
|
resolve(result);
|
|
1996
|
-
return;
|
|
1997
|
-
}
|
|
1998
|
-
try {
|
|
1999
|
-
resolve(onfulfilled(result));
|
|
2000
|
-
return;
|
|
2001
1869
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
1870
|
+
else {
|
|
1871
|
+
try {
|
|
1872
|
+
resolve(onfulfilled(result));
|
|
1873
|
+
}
|
|
1874
|
+
catch (e) {
|
|
1875
|
+
reject(e);
|
|
1876
|
+
}
|
|
2005
1877
|
}
|
|
2006
1878
|
},
|
|
2007
|
-
|
|
1879
|
+
reason => {
|
|
2008
1880
|
if (!onrejected) {
|
|
2009
1881
|
reject(reason);
|
|
2010
|
-
return;
|
|
2011
|
-
}
|
|
2012
|
-
try {
|
|
2013
|
-
resolve(onrejected(reason));
|
|
2014
|
-
return;
|
|
2015
1882
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
1883
|
+
else {
|
|
1884
|
+
try {
|
|
1885
|
+
resolve(onrejected(reason));
|
|
1886
|
+
}
|
|
1887
|
+
catch (e) {
|
|
1888
|
+
reject(e);
|
|
1889
|
+
}
|
|
2019
1890
|
}
|
|
2020
1891
|
},
|
|
2021
|
-
|
|
1892
|
+
]);
|
|
1893
|
+
this._executeHandlers();
|
|
2022
1894
|
});
|
|
2023
1895
|
}
|
|
2024
1896
|
/** JSDoc */
|
|
@@ -2051,24 +1923,25 @@ var Sentry = (function (exports) {
|
|
|
2051
1923
|
});
|
|
2052
1924
|
});
|
|
2053
1925
|
}
|
|
2054
|
-
/** JSDoc */
|
|
2055
|
-
toString() {
|
|
2056
|
-
return '[object SyncPromise]';
|
|
2057
|
-
}
|
|
2058
1926
|
}
|
|
2059
1927
|
|
|
2060
|
-
/**
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
1928
|
+
/**
|
|
1929
|
+
* Creates an new PromiseBuffer object with the specified limit
|
|
1930
|
+
* @param limit max number of promises that can be stored in the buffer
|
|
1931
|
+
*/
|
|
1932
|
+
function makePromiseBuffer(limit) {
|
|
1933
|
+
const buffer = [];
|
|
1934
|
+
function isReady() {
|
|
1935
|
+
return limit === undefined || buffer.length < limit;
|
|
2066
1936
|
}
|
|
2067
1937
|
/**
|
|
2068
|
-
*
|
|
1938
|
+
* Remove a promise from the queue.
|
|
1939
|
+
*
|
|
1940
|
+
* @param task Can be any PromiseLike<T>
|
|
1941
|
+
* @returns Removed promise.
|
|
2069
1942
|
*/
|
|
2070
|
-
|
|
2071
|
-
return
|
|
1943
|
+
function remove(task) {
|
|
1944
|
+
return buffer.splice(buffer.indexOf(task), 1)[0];
|
|
2072
1945
|
}
|
|
2073
1946
|
/**
|
|
2074
1947
|
* Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
|
|
@@ -2080,41 +1953,25 @@ var Sentry = (function (exports) {
|
|
|
2080
1953
|
* limit check.
|
|
2081
1954
|
* @returns The original promise.
|
|
2082
1955
|
*/
|
|
2083
|
-
add(taskProducer) {
|
|
2084
|
-
if (!
|
|
2085
|
-
return
|
|
1956
|
+
function add(taskProducer) {
|
|
1957
|
+
if (!isReady()) {
|
|
1958
|
+
return rejectedSyncPromise(new SentryError('Not adding Promise due to buffer limit reached.'));
|
|
2086
1959
|
}
|
|
2087
1960
|
// start the task and add its promise to the queue
|
|
2088
1961
|
const task = taskProducer();
|
|
2089
|
-
if (
|
|
2090
|
-
|
|
1962
|
+
if (buffer.indexOf(task) === -1) {
|
|
1963
|
+
buffer.push(task);
|
|
2091
1964
|
}
|
|
2092
1965
|
void task
|
|
2093
|
-
.then(() =>
|
|
1966
|
+
.then(() => remove(task))
|
|
2094
1967
|
// Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
|
|
2095
1968
|
// rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
|
|
2096
1969
|
// have promises, so TS has to polyfill when down-compiling.)
|
|
2097
|
-
.then(null, () =>
|
|
2098
|
-
// We have to add another catch here because `
|
|
1970
|
+
.then(null, () => remove(task).then(null, () => {
|
|
1971
|
+
// We have to add another catch here because `remove()` starts a new promise chain.
|
|
2099
1972
|
}));
|
|
2100
1973
|
return task;
|
|
2101
1974
|
}
|
|
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
1975
|
/**
|
|
2119
1976
|
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
|
|
2120
1977
|
*
|
|
@@ -2124,8 +1981,12 @@ var Sentry = (function (exports) {
|
|
|
2124
1981
|
* @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
|
|
2125
1982
|
* `false` otherwise
|
|
2126
1983
|
*/
|
|
2127
|
-
drain(timeout) {
|
|
2128
|
-
return new SyncPromise(resolve => {
|
|
1984
|
+
function drain(timeout) {
|
|
1985
|
+
return new SyncPromise((resolve, reject) => {
|
|
1986
|
+
let counter = buffer.length;
|
|
1987
|
+
if (!counter) {
|
|
1988
|
+
return resolve(true);
|
|
1989
|
+
}
|
|
2129
1990
|
// wait for `timeout` ms and then resolve to `false` (if not cancelled first)
|
|
2130
1991
|
const capturedSetTimeout = setTimeout(() => {
|
|
2131
1992
|
if (timeout && timeout > 0) {
|
|
@@ -2133,16 +1994,84 @@ var Sentry = (function (exports) {
|
|
|
2133
1994
|
}
|
|
2134
1995
|
}, timeout);
|
|
2135
1996
|
// if all promises resolve in time, cancel the timer and resolve to `true`
|
|
2136
|
-
|
|
2137
|
-
.then(() => {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
1997
|
+
buffer.forEach(item => {
|
|
1998
|
+
void resolvedSyncPromise(item).then(() => {
|
|
1999
|
+
// eslint-disable-next-line no-plusplus
|
|
2000
|
+
if (!--counter) {
|
|
2001
|
+
clearTimeout(capturedSetTimeout);
|
|
2002
|
+
resolve(true);
|
|
2003
|
+
}
|
|
2004
|
+
}, reject);
|
|
2143
2005
|
});
|
|
2144
2006
|
});
|
|
2145
2007
|
}
|
|
2008
|
+
return {
|
|
2009
|
+
$: buffer,
|
|
2010
|
+
add,
|
|
2011
|
+
drain,
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
/** JSDoc
|
|
2016
|
+
* @deprecated Use string literals - if you require type casting, cast to SeverityLevel type
|
|
2017
|
+
*/
|
|
2018
|
+
var Severity;
|
|
2019
|
+
(function (Severity) {
|
|
2020
|
+
/** JSDoc */
|
|
2021
|
+
Severity["Fatal"] = "fatal";
|
|
2022
|
+
/** JSDoc */
|
|
2023
|
+
Severity["Error"] = "error";
|
|
2024
|
+
/** JSDoc */
|
|
2025
|
+
Severity["Warning"] = "warning";
|
|
2026
|
+
/** JSDoc */
|
|
2027
|
+
Severity["Log"] = "log";
|
|
2028
|
+
/** JSDoc */
|
|
2029
|
+
Severity["Info"] = "info";
|
|
2030
|
+
/** JSDoc */
|
|
2031
|
+
Severity["Debug"] = "debug";
|
|
2032
|
+
/** JSDoc */
|
|
2033
|
+
Severity["Critical"] = "critical";
|
|
2034
|
+
})(Severity || (Severity = {}));
|
|
2035
|
+
const SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'];
|
|
2036
|
+
|
|
2037
|
+
function isSupportedSeverity(level) {
|
|
2038
|
+
return SeverityLevels.indexOf(level) !== -1;
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Converts a string-based level into a {@link Severity}.
|
|
2042
|
+
*
|
|
2043
|
+
* @param level string representation of Severity
|
|
2044
|
+
* @returns Severity
|
|
2045
|
+
*/
|
|
2046
|
+
function severityFromString(level) {
|
|
2047
|
+
if (level === 'warn')
|
|
2048
|
+
return 'warning';
|
|
2049
|
+
if (isSupportedSeverity(level)) {
|
|
2050
|
+
return level;
|
|
2051
|
+
}
|
|
2052
|
+
return 'log';
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
/**
|
|
2056
|
+
* Converts an HTTP status code to sentry status {@link EventStatus}.
|
|
2057
|
+
*
|
|
2058
|
+
* @param code number HTTP status code
|
|
2059
|
+
* @returns EventStatus
|
|
2060
|
+
*/
|
|
2061
|
+
function eventStatusFromHttpCode(code) {
|
|
2062
|
+
if (code >= 200 && code < 300) {
|
|
2063
|
+
return 'success';
|
|
2064
|
+
}
|
|
2065
|
+
if (code === 429) {
|
|
2066
|
+
return 'rate_limit';
|
|
2067
|
+
}
|
|
2068
|
+
if (code >= 400 && code < 500) {
|
|
2069
|
+
return 'invalid';
|
|
2070
|
+
}
|
|
2071
|
+
if (code >= 500) {
|
|
2072
|
+
return 'failed';
|
|
2073
|
+
}
|
|
2074
|
+
return 'unknown';
|
|
2146
2075
|
}
|
|
2147
2076
|
|
|
2148
2077
|
/**
|
|
@@ -2463,15 +2392,14 @@ var Sentry = (function (exports) {
|
|
|
2463
2392
|
* @inheritDoc
|
|
2464
2393
|
*/
|
|
2465
2394
|
getTransaction() {
|
|
2466
|
-
var _a, _b, _c, _d;
|
|
2467
2395
|
// often, this span will be a transaction, but it's not guaranteed to be
|
|
2468
2396
|
const span = this.getSpan();
|
|
2469
2397
|
// try it the new way first
|
|
2470
|
-
if (
|
|
2471
|
-
return
|
|
2398
|
+
if (span && span.transaction) {
|
|
2399
|
+
return span.transaction;
|
|
2472
2400
|
}
|
|
2473
2401
|
// fallback to the old way (known bug: this only finds transactions with sampled = true)
|
|
2474
|
-
if (
|
|
2402
|
+
if (span && span.spanRecorder && span.spanRecorder.spans[0]) {
|
|
2475
2403
|
return span.spanRecorder.spans[0];
|
|
2476
2404
|
}
|
|
2477
2405
|
// neither way found a transaction
|
|
@@ -2594,7 +2522,6 @@ var Sentry = (function (exports) {
|
|
|
2594
2522
|
* @hidden
|
|
2595
2523
|
*/
|
|
2596
2524
|
applyToEvent(event, hint) {
|
|
2597
|
-
var _a;
|
|
2598
2525
|
if (this._extra && Object.keys(this._extra).length) {
|
|
2599
2526
|
event.extra = Object.assign(Object.assign({}, this._extra), event.extra);
|
|
2600
2527
|
}
|
|
@@ -2618,7 +2545,7 @@ var Sentry = (function (exports) {
|
|
|
2618
2545
|
// errors with transaction and it relies on that.
|
|
2619
2546
|
if (this._span) {
|
|
2620
2547
|
event.contexts = Object.assign({ trace: this._span.getTraceContext() }, event.contexts);
|
|
2621
|
-
const transactionName =
|
|
2548
|
+
const transactionName = this._span.transaction && this._span.transaction.name;
|
|
2622
2549
|
if (transactionName) {
|
|
2623
2550
|
event.tags = Object.assign({ transaction: transactionName }, event.tags);
|
|
2624
2551
|
}
|
|
@@ -2715,7 +2642,7 @@ var Sentry = (function (exports) {
|
|
|
2715
2642
|
this.errors = 0;
|
|
2716
2643
|
this.sid = uuid4();
|
|
2717
2644
|
this.duration = 0;
|
|
2718
|
-
this.status =
|
|
2645
|
+
this.status = 'ok';
|
|
2719
2646
|
this.init = true;
|
|
2720
2647
|
this.ignoreDuration = false;
|
|
2721
2648
|
// Both timestamp and started are in seconds since the UNIX epoch.
|
|
@@ -2788,8 +2715,8 @@ var Sentry = (function (exports) {
|
|
|
2788
2715
|
if (status) {
|
|
2789
2716
|
this.update({ status });
|
|
2790
2717
|
}
|
|
2791
|
-
else if (this.status ===
|
|
2792
|
-
this.update({ status:
|
|
2718
|
+
else if (this.status === 'ok') {
|
|
2719
|
+
this.update({ status: 'exited' });
|
|
2793
2720
|
}
|
|
2794
2721
|
else {
|
|
2795
2722
|
this.update();
|
|
@@ -2807,17 +2734,16 @@ var Sentry = (function (exports) {
|
|
|
2807
2734
|
errors: this.errors,
|
|
2808
2735
|
did: typeof this.did === 'number' || typeof this.did === 'string' ? `${this.did}` : undefined,
|
|
2809
2736
|
duration: this.duration,
|
|
2810
|
-
attrs:
|
|
2737
|
+
attrs: {
|
|
2811
2738
|
release: this.release,
|
|
2812
2739
|
environment: this.environment,
|
|
2813
2740
|
ip_address: this.ipAddress,
|
|
2814
2741
|
user_agent: this.userAgent,
|
|
2815
|
-
}
|
|
2742
|
+
},
|
|
2816
2743
|
});
|
|
2817
2744
|
}
|
|
2818
2745
|
}
|
|
2819
2746
|
|
|
2820
|
-
/* eslint-disable max-lines */
|
|
2821
2747
|
/**
|
|
2822
2748
|
* API compatibility version of this hub.
|
|
2823
2749
|
*
|
|
@@ -3127,11 +3053,17 @@ var Sentry = (function (exports) {
|
|
|
3127
3053
|
* @inheritDoc
|
|
3128
3054
|
*/
|
|
3129
3055
|
endSession() {
|
|
3130
|
-
|
|
3131
|
-
|
|
3056
|
+
const layer = this.getStackTop();
|
|
3057
|
+
const scope = layer && layer.scope;
|
|
3058
|
+
const session = scope && scope.getSession();
|
|
3059
|
+
if (session) {
|
|
3060
|
+
session.close();
|
|
3061
|
+
}
|
|
3132
3062
|
this._sendSessionUpdate();
|
|
3133
3063
|
// the session is over; take it off of the scope
|
|
3134
|
-
|
|
3064
|
+
if (scope) {
|
|
3065
|
+
scope.setSession();
|
|
3066
|
+
}
|
|
3135
3067
|
}
|
|
3136
3068
|
/**
|
|
3137
3069
|
* @inheritDoc
|
|
@@ -3147,8 +3079,8 @@ var Sentry = (function (exports) {
|
|
|
3147
3079
|
if (scope) {
|
|
3148
3080
|
// End existing session if there's one
|
|
3149
3081
|
const currentSession = scope.getSession && scope.getSession();
|
|
3150
|
-
if (currentSession && currentSession.status ===
|
|
3151
|
-
currentSession.update({ status:
|
|
3082
|
+
if (currentSession && currentSession.status === 'ok') {
|
|
3083
|
+
currentSession.update({ status: 'exited' });
|
|
3152
3084
|
}
|
|
3153
3085
|
this.endSession();
|
|
3154
3086
|
// Afterwards we set the new session on the scope
|
|
@@ -3250,9 +3182,9 @@ var Sentry = (function (exports) {
|
|
|
3250
3182
|
* @returns discovered hub
|
|
3251
3183
|
*/
|
|
3252
3184
|
function getHubFromActiveDomain(registry) {
|
|
3253
|
-
var _a, _b, _c;
|
|
3254
3185
|
try {
|
|
3255
|
-
const
|
|
3186
|
+
const sentry = getMainCarrier().__SENTRY__;
|
|
3187
|
+
const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
|
|
3256
3188
|
// If there's no active domain, just return global hub
|
|
3257
3189
|
if (!activeDomain) {
|
|
3258
3190
|
return getHubFromCarrier(registry);
|
|
@@ -3343,7 +3275,7 @@ var Sentry = (function (exports) {
|
|
|
3343
3275
|
* Captures a message event and sends it to Sentry.
|
|
3344
3276
|
*
|
|
3345
3277
|
* @param message The message to send to Sentry.
|
|
3346
|
-
* @param
|
|
3278
|
+
* @param SeverityLevel Define the level of the message.
|
|
3347
3279
|
* @returns The generated eventId.
|
|
3348
3280
|
*/
|
|
3349
3281
|
function captureMessage(message, captureContext) {
|
|
@@ -3475,134 +3407,83 @@ var Sentry = (function (exports) {
|
|
|
3475
3407
|
}
|
|
3476
3408
|
|
|
3477
3409
|
const SENTRY_API_VERSION = '7';
|
|
3410
|
+
/** Initializes API Details */
|
|
3411
|
+
function initAPIDetails(dsn, metadata, tunnel) {
|
|
3412
|
+
return {
|
|
3413
|
+
initDsn: dsn,
|
|
3414
|
+
metadata: metadata || {},
|
|
3415
|
+
dsn: makeDsn(dsn),
|
|
3416
|
+
tunnel,
|
|
3417
|
+
};
|
|
3418
|
+
}
|
|
3419
|
+
/** Returns the prefix to construct Sentry ingestion API endpoints. */
|
|
3420
|
+
function getBaseApiEndpoint(dsn) {
|
|
3421
|
+
const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
|
|
3422
|
+
const port = dsn.port ? `:${dsn.port}` : '';
|
|
3423
|
+
return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
|
|
3424
|
+
}
|
|
3425
|
+
/** Returns the ingest API endpoint for target. */
|
|
3426
|
+
function _getIngestEndpoint(dsn, target) {
|
|
3427
|
+
return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/${target}/`;
|
|
3428
|
+
}
|
|
3429
|
+
/** Returns a URL-encoded string with auth config suitable for a query string. */
|
|
3430
|
+
function _encodedAuth(dsn) {
|
|
3431
|
+
return urlEncode({
|
|
3432
|
+
// We send only the minimum set of required information. See
|
|
3433
|
+
// https://github.com/getsentry/sentry-javascript/issues/2572.
|
|
3434
|
+
sentry_key: dsn.publicKey,
|
|
3435
|
+
sentry_version: SENTRY_API_VERSION,
|
|
3436
|
+
});
|
|
3437
|
+
}
|
|
3438
|
+
/** Returns the store endpoint URL. */
|
|
3439
|
+
function getStoreEndpoint(dsn) {
|
|
3440
|
+
return _getIngestEndpoint(dsn, 'store');
|
|
3441
|
+
}
|
|
3478
3442
|
/**
|
|
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}`);
|
|
3443
|
+
* Returns the store endpoint URL with auth in the query string.
|
|
3444
|
+
*
|
|
3445
|
+
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3446
|
+
*/
|
|
3447
|
+
function getStoreEndpointWithUrlEncodedAuth(dsn) {
|
|
3448
|
+
return `${getStoreEndpoint(dsn)}?${_encodedAuth(dsn)}`;
|
|
3449
|
+
}
|
|
3450
|
+
/** Returns the envelope endpoint URL. */
|
|
3451
|
+
function _getEnvelopeEndpoint(dsn) {
|
|
3452
|
+
return _getIngestEndpoint(dsn, 'envelope');
|
|
3453
|
+
}
|
|
3454
|
+
/**
|
|
3455
|
+
* Returns the envelope endpoint URL with auth in the query string.
|
|
3456
|
+
*
|
|
3457
|
+
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
|
|
3458
|
+
*/
|
|
3459
|
+
function getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel) {
|
|
3460
|
+
return tunnel ? tunnel : `${_getEnvelopeEndpoint(dsn)}?${_encodedAuth(dsn)}`;
|
|
3461
|
+
}
|
|
3462
|
+
/** Returns the url to the report dialog endpoint. */
|
|
3463
|
+
function getReportDialogEndpoint(dsnLike, dialogOptions) {
|
|
3464
|
+
const dsn = makeDsn(dsnLike);
|
|
3465
|
+
const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
|
|
3466
|
+
let encodedOptions = `dsn=${dsnToString(dsn)}`;
|
|
3467
|
+
for (const key in dialogOptions) {
|
|
3468
|
+
if (key === 'dsn') {
|
|
3469
|
+
continue;
|
|
3546
3470
|
}
|
|
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') {
|
|
3471
|
+
if (key === 'user') {
|
|
3472
|
+
if (!dialogOptions.user) {
|
|
3560
3473
|
continue;
|
|
3561
3474
|
}
|
|
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
|
-
}
|
|
3475
|
+
if (dialogOptions.user.name) {
|
|
3476
|
+
encodedOptions += `&name=${encodeURIComponent(dialogOptions.user.name)}`;
|
|
3572
3477
|
}
|
|
3573
|
-
|
|
3574
|
-
encodedOptions
|
|
3478
|
+
if (dialogOptions.user.email) {
|
|
3479
|
+
encodedOptions += `&email=${encodeURIComponent(dialogOptions.user.email)}`;
|
|
3575
3480
|
}
|
|
3576
3481
|
}
|
|
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;
|
|
3482
|
+
else {
|
|
3483
|
+
encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key])}`;
|
|
3590
3484
|
}
|
|
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
3485
|
}
|
|
3486
|
+
return `${endpoint}?${encodedOptions}`;
|
|
3606
3487
|
}
|
|
3607
3488
|
|
|
3608
3489
|
const installedIntegrations = [];
|
|
@@ -3666,7 +3547,7 @@ var Sentry = (function (exports) {
|
|
|
3666
3547
|
// set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty`
|
|
3667
3548
|
// because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be
|
|
3668
3549
|
// considered a member of the index the way the actual integrations are
|
|
3669
|
-
|
|
3550
|
+
addNonEnumerableProperty(integrations, 'initialized', true);
|
|
3670
3551
|
return integrations;
|
|
3671
3552
|
}
|
|
3672
3553
|
|
|
@@ -3719,7 +3600,7 @@ var Sentry = (function (exports) {
|
|
|
3719
3600
|
this._backend = new backendClass(options);
|
|
3720
3601
|
this._options = options;
|
|
3721
3602
|
if (options.dsn) {
|
|
3722
|
-
this._dsn =
|
|
3603
|
+
this._dsn = makeDsn(options.dsn);
|
|
3723
3604
|
}
|
|
3724
3605
|
}
|
|
3725
3606
|
/**
|
|
@@ -3760,9 +3641,8 @@ var Sentry = (function (exports) {
|
|
|
3760
3641
|
* @inheritDoc
|
|
3761
3642
|
*/
|
|
3762
3643
|
captureEvent(event, hint, scope) {
|
|
3763
|
-
var _a;
|
|
3764
3644
|
// ensure we haven't captured this very object before
|
|
3765
|
-
if (
|
|
3645
|
+
if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {
|
|
3766
3646
|
logger.log(ALREADY_SEEN_ERROR);
|
|
3767
3647
|
return;
|
|
3768
3648
|
}
|
|
@@ -3777,11 +3657,15 @@ var Sentry = (function (exports) {
|
|
|
3777
3657
|
*/
|
|
3778
3658
|
captureSession(session) {
|
|
3779
3659
|
if (!this._isEnabled()) {
|
|
3780
|
-
|
|
3660
|
+
if (isDebugBuild()) {
|
|
3661
|
+
logger.warn('SDK not enabled, will not capture session.');
|
|
3662
|
+
}
|
|
3781
3663
|
return;
|
|
3782
3664
|
}
|
|
3783
3665
|
if (!(typeof session.release === 'string')) {
|
|
3784
|
-
|
|
3666
|
+
if (isDebugBuild()) {
|
|
3667
|
+
logger.warn('Discarded session because of missing or non-string release');
|
|
3668
|
+
}
|
|
3785
3669
|
}
|
|
3786
3670
|
else {
|
|
3787
3671
|
this._sendSession(session);
|
|
@@ -3864,10 +3748,10 @@ var Sentry = (function (exports) {
|
|
|
3864
3748
|
// A session is updated and that session update is sent in only one of the two following scenarios:
|
|
3865
3749
|
// 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
|
|
3866
3750
|
// 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
|
|
3867
|
-
const sessionNonTerminal = session.status ===
|
|
3751
|
+
const sessionNonTerminal = session.status === 'ok';
|
|
3868
3752
|
const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
|
|
3869
3753
|
if (shouldUpdateAndSend) {
|
|
3870
|
-
session.update(Object.assign(Object.assign({}, (crashed && { status:
|
|
3754
|
+
session.update(Object.assign(Object.assign({}, (crashed && { status: 'crashed' })), { errors: session.errors || Number(errored || crashed) }));
|
|
3871
3755
|
this.captureSession(session);
|
|
3872
3756
|
}
|
|
3873
3757
|
}
|
|
@@ -3938,7 +3822,7 @@ var Sentry = (function (exports) {
|
|
|
3938
3822
|
finalScope = Scope.clone(finalScope).update(hint.captureContext);
|
|
3939
3823
|
}
|
|
3940
3824
|
// We prepare the result here with a resolved Event.
|
|
3941
|
-
let result =
|
|
3825
|
+
let result = resolvedSyncPromise(prepared);
|
|
3942
3826
|
// This should be the last thing called, since we want that
|
|
3943
3827
|
// {@link Hub.addEventProcessor} gets the finished prepared event.
|
|
3944
3828
|
if (finalScope) {
|
|
@@ -4070,26 +3954,29 @@ var Sentry = (function (exports) {
|
|
|
4070
3954
|
* @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
|
|
4071
3955
|
*/
|
|
4072
3956
|
_processEvent(event, hint, scope) {
|
|
4073
|
-
var _a, _b;
|
|
4074
3957
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
4075
3958
|
const { beforeSend, sampleRate } = this.getOptions();
|
|
4076
3959
|
const transport = this.getTransport();
|
|
3960
|
+
function recordLostEvent(outcome, category) {
|
|
3961
|
+
if (transport.recordLostEvent) {
|
|
3962
|
+
transport.recordLostEvent(outcome, category);
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
4077
3965
|
if (!this._isEnabled()) {
|
|
4078
|
-
return
|
|
3966
|
+
return rejectedSyncPromise(new SentryError('SDK not enabled, will not capture event.'));
|
|
4079
3967
|
}
|
|
4080
3968
|
const isTransaction = event.type === 'transaction';
|
|
4081
3969
|
// 1.0 === 100% events are sent
|
|
4082
3970
|
// 0.0 === 0% events are sent
|
|
4083
3971
|
// Sampling for transaction happens somewhere else
|
|
4084
3972
|
if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) {
|
|
4085
|
-
|
|
4086
|
-
return
|
|
3973
|
+
recordLostEvent('sample_rate', 'event');
|
|
3974
|
+
return rejectedSyncPromise(new SentryError(`Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`));
|
|
4087
3975
|
}
|
|
4088
3976
|
return this._prepareEvent(event, scope, hint)
|
|
4089
3977
|
.then(prepared => {
|
|
4090
|
-
var _a, _b;
|
|
4091
3978
|
if (prepared === null) {
|
|
4092
|
-
|
|
3979
|
+
recordLostEvent('event_processor', event.type || 'event');
|
|
4093
3980
|
throw new SentryError('An event processor returned null, will not send event.');
|
|
4094
3981
|
}
|
|
4095
3982
|
const isInternalException = hint && hint.data && hint.data.__sentry__ === true;
|
|
@@ -4097,12 +3984,11 @@ var Sentry = (function (exports) {
|
|
|
4097
3984
|
return prepared;
|
|
4098
3985
|
}
|
|
4099
3986
|
const beforeSendResult = beforeSend(prepared, hint);
|
|
4100
|
-
return
|
|
3987
|
+
return _ensureBeforeSendRv(beforeSendResult);
|
|
4101
3988
|
})
|
|
4102
3989
|
.then(processedEvent => {
|
|
4103
|
-
var _a, _b;
|
|
4104
3990
|
if (processedEvent === null) {
|
|
4105
|
-
|
|
3991
|
+
recordLostEvent('before_send', event.type || 'event');
|
|
4106
3992
|
throw new SentryError('`beforeSend` returned `null`, will not send event.');
|
|
4107
3993
|
}
|
|
4108
3994
|
const session = scope && scope.getSession && scope.getSession();
|
|
@@ -4138,26 +4024,26 @@ var Sentry = (function (exports) {
|
|
|
4138
4024
|
return reason;
|
|
4139
4025
|
});
|
|
4140
4026
|
}
|
|
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;
|
|
4027
|
+
}
|
|
4028
|
+
/**
|
|
4029
|
+
* Verifies that return value of configured `beforeSend` is of expected type.
|
|
4030
|
+
*/
|
|
4031
|
+
function _ensureBeforeSendRv(rv) {
|
|
4032
|
+
const nullErr = '`beforeSend` method has to return `null` or a valid event.';
|
|
4033
|
+
if (isThenable(rv)) {
|
|
4034
|
+
return rv.then(event => {
|
|
4035
|
+
if (!(isPlainObject(event) || event === null)) {
|
|
4036
|
+
throw new SentryError(nullErr);
|
|
4037
|
+
}
|
|
4038
|
+
return event;
|
|
4039
|
+
}, e => {
|
|
4040
|
+
throw new SentryError(`beforeSend rejected with ${e}`);
|
|
4041
|
+
});
|
|
4160
4042
|
}
|
|
4043
|
+
else if (!(isPlainObject(rv) || rv === null)) {
|
|
4044
|
+
throw new SentryError(nullErr);
|
|
4045
|
+
}
|
|
4046
|
+
return rv;
|
|
4161
4047
|
}
|
|
4162
4048
|
|
|
4163
4049
|
/** Noop transport */
|
|
@@ -4166,16 +4052,16 @@ var Sentry = (function (exports) {
|
|
|
4166
4052
|
* @inheritDoc
|
|
4167
4053
|
*/
|
|
4168
4054
|
sendEvent(_) {
|
|
4169
|
-
return
|
|
4055
|
+
return resolvedSyncPromise({
|
|
4170
4056
|
reason: `NoopTransport: Event has been skipped because no Dsn is configured.`,
|
|
4171
|
-
status:
|
|
4057
|
+
status: 'skipped',
|
|
4172
4058
|
});
|
|
4173
4059
|
}
|
|
4174
4060
|
/**
|
|
4175
4061
|
* @inheritDoc
|
|
4176
4062
|
*/
|
|
4177
4063
|
close(_) {
|
|
4178
|
-
return
|
|
4064
|
+
return resolvedSyncPromise(true);
|
|
4179
4065
|
}
|
|
4180
4066
|
}
|
|
4181
4067
|
|
|
@@ -4210,7 +4096,9 @@ var Sentry = (function (exports) {
|
|
|
4210
4096
|
*/
|
|
4211
4097
|
sendEvent(event) {
|
|
4212
4098
|
void this._transport.sendEvent(event).then(null, reason => {
|
|
4213
|
-
|
|
4099
|
+
if (isDebugBuild()) {
|
|
4100
|
+
logger.error(`Error while sending event: ${reason}`);
|
|
4101
|
+
}
|
|
4214
4102
|
});
|
|
4215
4103
|
}
|
|
4216
4104
|
/**
|
|
@@ -4218,11 +4106,15 @@ var Sentry = (function (exports) {
|
|
|
4218
4106
|
*/
|
|
4219
4107
|
sendSession(session) {
|
|
4220
4108
|
if (!this._transport.sendSession) {
|
|
4221
|
-
|
|
4109
|
+
if (isDebugBuild()) {
|
|
4110
|
+
logger.warn("Dropping session because custom transport doesn't implement sendSession");
|
|
4111
|
+
}
|
|
4222
4112
|
return;
|
|
4223
4113
|
}
|
|
4224
4114
|
void this._transport.sendSession(session).then(null, reason => {
|
|
4225
|
-
|
|
4115
|
+
if (isDebugBuild()) {
|
|
4116
|
+
logger.error(`Error while sending session: ${reason}`);
|
|
4117
|
+
}
|
|
4226
4118
|
});
|
|
4227
4119
|
}
|
|
4228
4120
|
/**
|
|
@@ -4290,7 +4182,7 @@ var Sentry = (function (exports) {
|
|
|
4290
4182
|
/** Creates a SentryRequest from a Session. */
|
|
4291
4183
|
function sessionToSentryRequest(session, api) {
|
|
4292
4184
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4293
|
-
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.
|
|
4185
|
+
const envelopeHeaders = JSON.stringify(Object.assign(Object.assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: dsnToString(api.dsn) })));
|
|
4294
4186
|
// I know this is hacky but we don't want to add `session` to request type since it's never rate limited
|
|
4295
4187
|
const type = 'aggregates' in session ? 'sessions' : 'session';
|
|
4296
4188
|
const itemHeaders = JSON.stringify({
|
|
@@ -4299,14 +4191,14 @@ var Sentry = (function (exports) {
|
|
|
4299
4191
|
return {
|
|
4300
4192
|
body: `${envelopeHeaders}\n${itemHeaders}\n${JSON.stringify(session)}`,
|
|
4301
4193
|
type,
|
|
4302
|
-
url: api.
|
|
4194
|
+
url: getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel),
|
|
4303
4195
|
};
|
|
4304
4196
|
}
|
|
4305
4197
|
/** Creates a SentryRequest from an event. */
|
|
4306
4198
|
function eventToSentryRequest(event, api) {
|
|
4307
4199
|
const sdkInfo = getSdkMetadataForEnvelopeHeader(api);
|
|
4308
4200
|
const eventType = event.type || 'event';
|
|
4309
|
-
const useEnvelope = eventType === 'transaction' || api.
|
|
4201
|
+
const useEnvelope = eventType === 'transaction' || !!api.tunnel;
|
|
4310
4202
|
const _a = event.debug_meta || {}, { transactionSampling } = _a, metadata = __rest(_a, ["transactionSampling"]);
|
|
4311
4203
|
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
|
|
4312
4204
|
if (Object.keys(metadata).length === 0) {
|
|
@@ -4318,7 +4210,9 @@ var Sentry = (function (exports) {
|
|
|
4318
4210
|
const req = {
|
|
4319
4211
|
body: JSON.stringify(sdkInfo ? enhanceEventWithSdkInfo(event, api.metadata.sdk) : event),
|
|
4320
4212
|
type: eventType,
|
|
4321
|
-
url: useEnvelope
|
|
4213
|
+
url: useEnvelope
|
|
4214
|
+
? getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel)
|
|
4215
|
+
: getStoreEndpointWithUrlEncodedAuth(api.dsn),
|
|
4322
4216
|
};
|
|
4323
4217
|
// https://develop.sentry.dev/sdk/envelopes/
|
|
4324
4218
|
// Since we don't need to manipulate envelopes nor store them, there is no
|
|
@@ -4326,7 +4220,7 @@ var Sentry = (function (exports) {
|
|
|
4326
4220
|
// deserialization. Instead, we only implement a minimal subset of the spec to
|
|
4327
4221
|
// serialize events inline here.
|
|
4328
4222
|
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.
|
|
4223
|
+
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
4224
|
const itemHeaders = JSON.stringify({
|
|
4331
4225
|
type: eventType,
|
|
4332
4226
|
// TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
|
|
@@ -4351,17 +4245,19 @@ var Sentry = (function (exports) {
|
|
|
4351
4245
|
* @param options Options to pass to the client.
|
|
4352
4246
|
*/
|
|
4353
4247
|
function initAndBind(clientClass, options) {
|
|
4354
|
-
var _a;
|
|
4355
4248
|
if (options.debug === true) {
|
|
4356
4249
|
logger.enable();
|
|
4357
4250
|
}
|
|
4358
4251
|
const hub = getCurrentHub();
|
|
4359
|
-
|
|
4252
|
+
const scope = hub.getScope();
|
|
4253
|
+
if (scope) {
|
|
4254
|
+
scope.update(options.initialScope);
|
|
4255
|
+
}
|
|
4360
4256
|
const client = new clientClass(options);
|
|
4361
4257
|
hub.bindClient(client);
|
|
4362
4258
|
}
|
|
4363
4259
|
|
|
4364
|
-
const SDK_VERSION = '6.
|
|
4260
|
+
const SDK_VERSION = '6.17.0-beta.0';
|
|
4365
4261
|
|
|
4366
4262
|
let originalFunctionToString;
|
|
4367
4263
|
/** Patch toString calls to return proper name for wrapped functions */
|
|
@@ -4380,7 +4276,7 @@ var Sentry = (function (exports) {
|
|
|
4380
4276
|
originalFunctionToString = Function.prototype.toString;
|
|
4381
4277
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4382
4278
|
Function.prototype.toString = function (...args) {
|
|
4383
|
-
const context = this
|
|
4279
|
+
const context = getOriginalFunction(this) || this;
|
|
4384
4280
|
return originalFunctionToString.apply(context, args);
|
|
4385
4281
|
};
|
|
4386
4282
|
}
|
|
@@ -4432,19 +4328,27 @@ var Sentry = (function (exports) {
|
|
|
4432
4328
|
/** JSDoc */
|
|
4433
4329
|
_shouldDropEvent(event, options) {
|
|
4434
4330
|
if (this._isSentryError(event, options)) {
|
|
4435
|
-
|
|
4331
|
+
if (isDebugBuild()) {
|
|
4332
|
+
logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
|
|
4333
|
+
}
|
|
4436
4334
|
return true;
|
|
4437
4335
|
}
|
|
4438
4336
|
if (this._isIgnoredError(event, options)) {
|
|
4439
|
-
|
|
4337
|
+
if (isDebugBuild()) {
|
|
4338
|
+
logger.warn(`Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`);
|
|
4339
|
+
}
|
|
4440
4340
|
return true;
|
|
4441
4341
|
}
|
|
4442
4342
|
if (this._isDeniedUrl(event, options)) {
|
|
4443
|
-
|
|
4343
|
+
if (isDebugBuild()) {
|
|
4344
|
+
logger.warn(`Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4345
|
+
}
|
|
4444
4346
|
return true;
|
|
4445
4347
|
}
|
|
4446
4348
|
if (!this._isAllowedUrl(event, options)) {
|
|
4447
|
-
|
|
4349
|
+
if (isDebugBuild()) {
|
|
4350
|
+
logger.warn(`Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(event)}.\nUrl: ${this._getEventFilterUrl(event)}`);
|
|
4351
|
+
}
|
|
4448
4352
|
return true;
|
|
4449
4353
|
}
|
|
4450
4354
|
return false;
|
|
@@ -4455,16 +4359,14 @@ var Sentry = (function (exports) {
|
|
|
4455
4359
|
return false;
|
|
4456
4360
|
}
|
|
4457
4361
|
try {
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
event.exception.values[0] &&
|
|
4462
|
-
event.exception.values[0].type === 'SentryError') ||
|
|
4463
|
-
false);
|
|
4362
|
+
// @ts-ignore can't be a sentry error if undefined
|
|
4363
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
4364
|
+
return event.exception.values[0].type === 'SentryError';
|
|
4464
4365
|
}
|
|
4465
|
-
catch (
|
|
4466
|
-
|
|
4366
|
+
catch (e) {
|
|
4367
|
+
// ignore
|
|
4467
4368
|
}
|
|
4369
|
+
return false;
|
|
4468
4370
|
}
|
|
4469
4371
|
/** JSDoc */
|
|
4470
4372
|
_isIgnoredError(event, options) {
|
|
@@ -4531,7 +4433,9 @@ var Sentry = (function (exports) {
|
|
|
4531
4433
|
return [`${value}`, `${type}: ${value}`];
|
|
4532
4434
|
}
|
|
4533
4435
|
catch (oO) {
|
|
4534
|
-
|
|
4436
|
+
if (isDebugBuild()) {
|
|
4437
|
+
logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
|
|
4438
|
+
}
|
|
4535
4439
|
return [];
|
|
4536
4440
|
}
|
|
4537
4441
|
}
|
|
@@ -4539,10 +4443,9 @@ var Sentry = (function (exports) {
|
|
|
4539
4443
|
}
|
|
4540
4444
|
/** JSDoc */
|
|
4541
4445
|
_getLastValidUrl(frames = []) {
|
|
4542
|
-
var _a, _b;
|
|
4543
4446
|
for (let i = frames.length - 1; i >= 0; i--) {
|
|
4544
4447
|
const frame = frames[i];
|
|
4545
|
-
if (
|
|
4448
|
+
if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
|
|
4546
4449
|
return frame.filename || null;
|
|
4547
4450
|
}
|
|
4548
4451
|
}
|
|
@@ -4552,17 +4455,22 @@ var Sentry = (function (exports) {
|
|
|
4552
4455
|
_getEventFilterUrl(event) {
|
|
4553
4456
|
try {
|
|
4554
4457
|
if (event.stacktrace) {
|
|
4555
|
-
|
|
4556
|
-
|
|
4458
|
+
return this._getLastValidUrl(event.stacktrace.frames);
|
|
4459
|
+
}
|
|
4460
|
+
let frames;
|
|
4461
|
+
try {
|
|
4462
|
+
// @ts-ignore we only care about frames if the whole thing here is defined
|
|
4463
|
+
frames = event.exception.values[0].stacktrace.frames;
|
|
4557
4464
|
}
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
return this._getLastValidUrl(frames);
|
|
4465
|
+
catch (e) {
|
|
4466
|
+
// ignore
|
|
4561
4467
|
}
|
|
4562
|
-
return null;
|
|
4468
|
+
return frames ? this._getLastValidUrl(frames) : null;
|
|
4563
4469
|
}
|
|
4564
4470
|
catch (oO) {
|
|
4565
|
-
|
|
4471
|
+
if (isDebugBuild()) {
|
|
4472
|
+
logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
|
|
4473
|
+
}
|
|
4566
4474
|
return null;
|
|
4567
4475
|
}
|
|
4568
4476
|
}
|
|
@@ -4933,17 +4841,17 @@ var Sentry = (function (exports) {
|
|
|
4933
4841
|
attachStacktrace: options.attachStacktrace,
|
|
4934
4842
|
});
|
|
4935
4843
|
addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
|
|
4936
|
-
event.level =
|
|
4844
|
+
event.level = 'error';
|
|
4937
4845
|
if (hint && hint.event_id) {
|
|
4938
4846
|
event.event_id = hint.event_id;
|
|
4939
4847
|
}
|
|
4940
|
-
return
|
|
4848
|
+
return resolvedSyncPromise(event);
|
|
4941
4849
|
}
|
|
4942
4850
|
/**
|
|
4943
4851
|
* Builds and Event from a Message
|
|
4944
4852
|
* @hidden
|
|
4945
4853
|
*/
|
|
4946
|
-
function eventFromMessage(options, message, level =
|
|
4854
|
+
function eventFromMessage(options, message, level = 'info', hint) {
|
|
4947
4855
|
const syntheticException = (hint && hint.syntheticException) || undefined;
|
|
4948
4856
|
const event = eventFromString(message, syntheticException, {
|
|
4949
4857
|
attachStacktrace: options.attachStacktrace,
|
|
@@ -4952,7 +4860,7 @@ var Sentry = (function (exports) {
|
|
|
4952
4860
|
if (hint && hint.event_id) {
|
|
4953
4861
|
event.event_id = hint.event_id;
|
|
4954
4862
|
}
|
|
4955
|
-
return
|
|
4863
|
+
return resolvedSyncPromise(event);
|
|
4956
4864
|
}
|
|
4957
4865
|
/**
|
|
4958
4866
|
* @hidden
|
|
@@ -4967,16 +4875,24 @@ var Sentry = (function (exports) {
|
|
|
4967
4875
|
event = eventFromStacktrace(computeStackTrace(exception));
|
|
4968
4876
|
return event;
|
|
4969
4877
|
}
|
|
4878
|
+
// If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
|
|
4879
|
+
// and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
|
|
4880
|
+
// `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.
|
|
4881
|
+
//
|
|
4882
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/DOMError
|
|
4883
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/DOMException
|
|
4884
|
+
// https://webidl.spec.whatwg.org/#es-DOMException-specialness
|
|
4970
4885
|
if (isDOMError(exception) || isDOMException(exception)) {
|
|
4971
|
-
// If it is a DOMError or DOMException (which are legacy APIs, but still supported in some browsers)
|
|
4972
|
-
// then we just extract the name, code, and message, as they don't provide anything else
|
|
4973
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/DOMError
|
|
4974
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/DOMException
|
|
4975
4886
|
const domException = exception;
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4887
|
+
if ('stack' in exception) {
|
|
4888
|
+
event = eventFromStacktrace(computeStackTrace(exception));
|
|
4889
|
+
}
|
|
4890
|
+
else {
|
|
4891
|
+
const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');
|
|
4892
|
+
const message = domException.message ? `${name}: ${domException.message}` : name;
|
|
4893
|
+
event = eventFromString(message, syntheticException, options);
|
|
4894
|
+
addExceptionTypeValue(event, message);
|
|
4895
|
+
}
|
|
4980
4896
|
if ('code' in domException) {
|
|
4981
4897
|
event.tags = Object.assign(Object.assign({}, event.tags), { 'DOMException.code': `${domException.code}` });
|
|
4982
4898
|
}
|
|
@@ -5072,7 +4988,6 @@ var Sentry = (function (exports) {
|
|
|
5072
4988
|
* Safari: resource blocked by content blocker
|
|
5073
4989
|
*/
|
|
5074
4990
|
function getNativeFetchImplementation() {
|
|
5075
|
-
var _a, _b;
|
|
5076
4991
|
if (cachedFetchImpl) {
|
|
5077
4992
|
return cachedFetchImpl;
|
|
5078
4993
|
}
|
|
@@ -5084,18 +4999,21 @@ var Sentry = (function (exports) {
|
|
|
5084
4999
|
const document = global$3.document;
|
|
5085
5000
|
let fetchImpl = global$3.fetch;
|
|
5086
5001
|
// eslint-disable-next-line deprecation/deprecation
|
|
5087
|
-
if (
|
|
5002
|
+
if (document && typeof document.createElement === `function`) {
|
|
5088
5003
|
try {
|
|
5089
5004
|
const sandbox = document.createElement('iframe');
|
|
5090
5005
|
sandbox.hidden = true;
|
|
5091
5006
|
document.head.appendChild(sandbox);
|
|
5092
|
-
|
|
5093
|
-
|
|
5007
|
+
const contentWindow = sandbox.contentWindow;
|
|
5008
|
+
if (contentWindow && contentWindow.fetch) {
|
|
5009
|
+
fetchImpl = contentWindow.fetch;
|
|
5094
5010
|
}
|
|
5095
5011
|
document.head.removeChild(sandbox);
|
|
5096
5012
|
}
|
|
5097
5013
|
catch (e) {
|
|
5098
|
-
|
|
5014
|
+
if (isDebugBuild()) {
|
|
5015
|
+
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
|
|
5016
|
+
}
|
|
5099
5017
|
}
|
|
5100
5018
|
}
|
|
5101
5019
|
return (cachedFetchImpl = fetchImpl.bind(global$3));
|
|
@@ -5126,25 +5044,23 @@ var Sentry = (function (exports) {
|
|
|
5126
5044
|
}
|
|
5127
5045
|
}
|
|
5128
5046
|
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
attachment: 'attachment',
|
|
5134
|
-
};
|
|
5047
|
+
function requestTypeToCategory(ty) {
|
|
5048
|
+
const tyStr = ty;
|
|
5049
|
+
return tyStr === 'event' ? 'error' : tyStr;
|
|
5050
|
+
}
|
|
5135
5051
|
const global$4 = getGlobalObject();
|
|
5136
5052
|
/** Base Transport class implementation */
|
|
5137
5053
|
class BaseTransport {
|
|
5138
5054
|
constructor(options) {
|
|
5139
5055
|
this.options = options;
|
|
5140
5056
|
/** A simple buffer holding all requests. */
|
|
5141
|
-
this._buffer =
|
|
5057
|
+
this._buffer = makePromiseBuffer(30);
|
|
5142
5058
|
/** Locks transport after receiving rate limits in a response */
|
|
5143
5059
|
this._rateLimits = {};
|
|
5144
5060
|
this._outcomes = {};
|
|
5145
|
-
this._api =
|
|
5061
|
+
this._api = initAPIDetails(options.dsn, options._metadata, options.tunnel);
|
|
5146
5062
|
// eslint-disable-next-line deprecation/deprecation
|
|
5147
|
-
this.url = this._api.
|
|
5063
|
+
this.url = getStoreEndpointWithUrlEncodedAuth(this._api.dsn);
|
|
5148
5064
|
if (this.options.sendClientReports && global$4.document) {
|
|
5149
5065
|
global$4.document.addEventListener('visibilitychange', () => {
|
|
5150
5066
|
if (global$4.document.visibilityState === 'hidden') {
|
|
@@ -5156,8 +5072,14 @@ var Sentry = (function (exports) {
|
|
|
5156
5072
|
/**
|
|
5157
5073
|
* @inheritDoc
|
|
5158
5074
|
*/
|
|
5159
|
-
sendEvent(
|
|
5160
|
-
|
|
5075
|
+
sendEvent(event) {
|
|
5076
|
+
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5077
|
+
}
|
|
5078
|
+
/**
|
|
5079
|
+
* @inheritDoc
|
|
5080
|
+
*/
|
|
5081
|
+
sendSession(session) {
|
|
5082
|
+
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5161
5083
|
}
|
|
5162
5084
|
/**
|
|
5163
5085
|
* @inheritDoc
|
|
@@ -5178,7 +5100,7 @@ var Sentry = (function (exports) {
|
|
|
5178
5100
|
// We could use nested maps, but it's much easier to read and type this way.
|
|
5179
5101
|
// A correct type for map-based implementation if we want to go that route
|
|
5180
5102
|
// would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
|
|
5181
|
-
const key = `${
|
|
5103
|
+
const key = `${requestTypeToCategory(category)}:${reason}`;
|
|
5182
5104
|
logger.log(`Adding outcome: ${key}`);
|
|
5183
5105
|
this._outcomes[key] = (_a = this._outcomes[key], (_a !== null && _a !== void 0 ? _a : 0)) + 1;
|
|
5184
5106
|
}
|
|
@@ -5197,9 +5119,9 @@ var Sentry = (function (exports) {
|
|
|
5197
5119
|
return;
|
|
5198
5120
|
}
|
|
5199
5121
|
logger.log(`Flushing outcomes:\n${JSON.stringify(outcomes, null, 2)}`);
|
|
5200
|
-
const url = this._api.
|
|
5122
|
+
const url = getEnvelopeEndpointWithUrlEncodedAuth(this._api.dsn, this._api.tunnel);
|
|
5201
5123
|
// Envelope header is required to be at least an empty object
|
|
5202
|
-
const envelopeHeader = JSON.stringify(Object.assign({}, (this.
|
|
5124
|
+
const envelopeHeader = JSON.stringify(Object.assign({}, (this._api.tunnel && { dsn: dsnToString(this._api.dsn) })));
|
|
5203
5125
|
const itemHeaders = JSON.stringify({
|
|
5204
5126
|
type: 'client_report',
|
|
5205
5127
|
});
|
|
@@ -5226,15 +5148,16 @@ var Sentry = (function (exports) {
|
|
|
5226
5148
|
* Handle Sentry repsonse for promise-based transports.
|
|
5227
5149
|
*/
|
|
5228
5150
|
_handleResponse({ requestType, response, headers, resolve, reject, }) {
|
|
5229
|
-
const status =
|
|
5151
|
+
const status = eventStatusFromHttpCode(response.status);
|
|
5230
5152
|
/**
|
|
5231
5153
|
* "The name is case-insensitive."
|
|
5232
5154
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
|
|
5233
5155
|
*/
|
|
5234
5156
|
const limited = this._handleRateLimit(headers);
|
|
5235
|
-
if (limited)
|
|
5157
|
+
if (limited && isDebugBuild()) {
|
|
5236
5158
|
logger.warn(`Too many ${requestType} requests, backing off until: ${this._disabledUntil(requestType)}`);
|
|
5237
|
-
|
|
5159
|
+
}
|
|
5160
|
+
if (status === 'success') {
|
|
5238
5161
|
resolve({ status });
|
|
5239
5162
|
return;
|
|
5240
5163
|
}
|
|
@@ -5244,7 +5167,7 @@ var Sentry = (function (exports) {
|
|
|
5244
5167
|
* Gets the time that given category is disabled until for rate limiting
|
|
5245
5168
|
*/
|
|
5246
5169
|
_disabledUntil(requestType) {
|
|
5247
|
-
const category =
|
|
5170
|
+
const category = requestTypeToCategory(requestType);
|
|
5248
5171
|
return this._rateLimits[category] || this._rateLimits.all;
|
|
5249
5172
|
}
|
|
5250
5173
|
/**
|
|
@@ -5295,25 +5218,13 @@ var Sentry = (function (exports) {
|
|
|
5295
5218
|
super(options);
|
|
5296
5219
|
this._fetch = fetchImpl;
|
|
5297
5220
|
}
|
|
5298
|
-
/**
|
|
5299
|
-
* @inheritDoc
|
|
5300
|
-
*/
|
|
5301
|
-
sendEvent(event) {
|
|
5302
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5303
|
-
}
|
|
5304
|
-
/**
|
|
5305
|
-
* @inheritDoc
|
|
5306
|
-
*/
|
|
5307
|
-
sendSession(session) {
|
|
5308
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5309
|
-
}
|
|
5310
5221
|
/**
|
|
5311
5222
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5312
5223
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5313
5224
|
*/
|
|
5314
5225
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5315
5226
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5316
|
-
this.recordLostEvent(
|
|
5227
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5317
5228
|
return Promise.reject({
|
|
5318
5229
|
event: originalPayload,
|
|
5319
5230
|
type: sentryRequest.type,
|
|
@@ -5357,10 +5268,10 @@ var Sentry = (function (exports) {
|
|
|
5357
5268
|
.then(undefined, reason => {
|
|
5358
5269
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5359
5270
|
if (reason instanceof SentryError) {
|
|
5360
|
-
this.recordLostEvent(
|
|
5271
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5361
5272
|
}
|
|
5362
5273
|
else {
|
|
5363
|
-
this.recordLostEvent(
|
|
5274
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5364
5275
|
}
|
|
5365
5276
|
throw reason;
|
|
5366
5277
|
});
|
|
@@ -5369,25 +5280,13 @@ var Sentry = (function (exports) {
|
|
|
5369
5280
|
|
|
5370
5281
|
/** `XHR` based transport */
|
|
5371
5282
|
class XHRTransport extends BaseTransport {
|
|
5372
|
-
/**
|
|
5373
|
-
* @inheritDoc
|
|
5374
|
-
*/
|
|
5375
|
-
sendEvent(event) {
|
|
5376
|
-
return this._sendRequest(eventToSentryRequest(event, this._api), event);
|
|
5377
|
-
}
|
|
5378
|
-
/**
|
|
5379
|
-
* @inheritDoc
|
|
5380
|
-
*/
|
|
5381
|
-
sendSession(session) {
|
|
5382
|
-
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
|
|
5383
|
-
}
|
|
5384
5283
|
/**
|
|
5385
5284
|
* @param sentryRequest Prepared SentryRequest to be delivered
|
|
5386
5285
|
* @param originalPayload Original payload used to create SentryRequest
|
|
5387
5286
|
*/
|
|
5388
5287
|
_sendRequest(sentryRequest, originalPayload) {
|
|
5389
5288
|
if (this._isRateLimited(sentryRequest.type)) {
|
|
5390
|
-
this.recordLostEvent(
|
|
5289
|
+
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
|
|
5391
5290
|
return Promise.reject({
|
|
5392
5291
|
event: originalPayload,
|
|
5393
5292
|
type: sentryRequest.type,
|
|
@@ -5418,10 +5317,10 @@ var Sentry = (function (exports) {
|
|
|
5418
5317
|
.then(undefined, reason => {
|
|
5419
5318
|
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
|
|
5420
5319
|
if (reason instanceof SentryError) {
|
|
5421
|
-
this.recordLostEvent(
|
|
5320
|
+
this.recordLostEvent('queue_overflow', sentryRequest.type);
|
|
5422
5321
|
}
|
|
5423
5322
|
else {
|
|
5424
|
-
this.recordLostEvent(
|
|
5323
|
+
this.recordLostEvent('network_error', sentryRequest.type);
|
|
5425
5324
|
}
|
|
5426
5325
|
throw reason;
|
|
5427
5326
|
});
|
|
@@ -5451,7 +5350,7 @@ var Sentry = (function (exports) {
|
|
|
5451
5350
|
/**
|
|
5452
5351
|
* @inheritDoc
|
|
5453
5352
|
*/
|
|
5454
|
-
eventFromMessage(message, level =
|
|
5353
|
+
eventFromMessage(message, level = 'info', hint) {
|
|
5455
5354
|
return eventFromMessage(this._options, message, level, hint);
|
|
5456
5355
|
}
|
|
5457
5356
|
/**
|
|
@@ -5500,18 +5399,26 @@ var Sentry = (function (exports) {
|
|
|
5500
5399
|
* @hidden
|
|
5501
5400
|
*/
|
|
5502
5401
|
function wrap(fn, options = {}, before) {
|
|
5402
|
+
// for future readers what this does is wrap a function and then create
|
|
5403
|
+
// a bi-directional wrapping between them.
|
|
5404
|
+
//
|
|
5405
|
+
// example: wrapped = wrap(original);
|
|
5406
|
+
// original.__sentry_wrapped__ -> wrapped
|
|
5407
|
+
// wrapped.__sentry_original__ -> original
|
|
5503
5408
|
if (typeof fn !== 'function') {
|
|
5504
5409
|
return fn;
|
|
5505
5410
|
}
|
|
5506
5411
|
try {
|
|
5412
|
+
// if we're dealing with a function that was previously wrapped, return
|
|
5413
|
+
// the original wrapper.
|
|
5414
|
+
const wrapper = fn.__sentry_wrapped__;
|
|
5415
|
+
if (wrapper) {
|
|
5416
|
+
return wrapper;
|
|
5417
|
+
}
|
|
5507
5418
|
// We don't wanna wrap it twice
|
|
5508
|
-
if (fn
|
|
5419
|
+
if (getOriginalFunction(fn)) {
|
|
5509
5420
|
return fn;
|
|
5510
5421
|
}
|
|
5511
|
-
// If this has already been wrapped in the past, return that wrapped function
|
|
5512
|
-
if (fn.__sentry_wrapped__) {
|
|
5513
|
-
return fn.__sentry_wrapped__;
|
|
5514
|
-
}
|
|
5515
5422
|
}
|
|
5516
5423
|
catch (e) {
|
|
5517
5424
|
// Just accessing custom props in some Selenium environments
|
|
@@ -5529,14 +5436,6 @@ var Sentry = (function (exports) {
|
|
|
5529
5436
|
}
|
|
5530
5437
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
5531
5438
|
const wrappedArguments = args.map((arg) => wrap(arg, options));
|
|
5532
|
-
if (fn.handleEvent) {
|
|
5533
|
-
// Attempt to invoke user-land function
|
|
5534
|
-
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5535
|
-
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
5536
|
-
// is expected behavior and NOT indicative of a bug with sentry.javascript.
|
|
5537
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5538
|
-
return fn.handleEvent.apply(this, wrappedArguments);
|
|
5539
|
-
}
|
|
5540
5439
|
// Attempt to invoke user-land function
|
|
5541
5440
|
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
|
|
5542
5441
|
// means the sentry.javascript SDK caught an error invoking your application code. This
|
|
@@ -5547,13 +5446,12 @@ var Sentry = (function (exports) {
|
|
|
5547
5446
|
ignoreNextOnError();
|
|
5548
5447
|
withScope((scope) => {
|
|
5549
5448
|
scope.addEventProcessor((event) => {
|
|
5550
|
-
const processedEvent = Object.assign({}, event);
|
|
5551
5449
|
if (options.mechanism) {
|
|
5552
|
-
addExceptionTypeValue(
|
|
5553
|
-
addExceptionMechanism(
|
|
5450
|
+
addExceptionTypeValue(event, undefined, undefined);
|
|
5451
|
+
addExceptionMechanism(event, options.mechanism);
|
|
5554
5452
|
}
|
|
5555
|
-
|
|
5556
|
-
return
|
|
5453
|
+
event.extra = Object.assign(Object.assign({}, event.extra), { arguments: args });
|
|
5454
|
+
return event;
|
|
5557
5455
|
});
|
|
5558
5456
|
captureException(ex);
|
|
5559
5457
|
});
|
|
@@ -5571,24 +5469,10 @@ var Sentry = (function (exports) {
|
|
|
5571
5469
|
}
|
|
5572
5470
|
}
|
|
5573
5471
|
catch (_oO) { } // eslint-disable-line no-empty
|
|
5574
|
-
fn.prototype = fn.prototype || {};
|
|
5575
|
-
sentryWrapped.prototype = fn.prototype;
|
|
5576
|
-
Object.defineProperty(fn, '__sentry_wrapped__', {
|
|
5577
|
-
enumerable: false,
|
|
5578
|
-
value: sentryWrapped,
|
|
5579
|
-
});
|
|
5580
5472
|
// Signal that this function has been wrapped/filled already
|
|
5581
5473
|
// for both debugging and to prevent it to being wrapped/filled twice
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
enumerable: false,
|
|
5585
|
-
value: true,
|
|
5586
|
-
},
|
|
5587
|
-
__sentry_original__: {
|
|
5588
|
-
enumerable: false,
|
|
5589
|
-
value: fn,
|
|
5590
|
-
},
|
|
5591
|
-
});
|
|
5474
|
+
markFunctionWrapped(sentryWrapped, fn);
|
|
5475
|
+
addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);
|
|
5592
5476
|
// Restore original function name (not all browsers allow that)
|
|
5593
5477
|
try {
|
|
5594
5478
|
const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name');
|
|
@@ -5613,16 +5497,20 @@ var Sentry = (function (exports) {
|
|
|
5613
5497
|
return;
|
|
5614
5498
|
}
|
|
5615
5499
|
if (!options.eventId) {
|
|
5616
|
-
|
|
5500
|
+
if (isDebugBuild()) {
|
|
5501
|
+
logger.error(`Missing eventId option in showReportDialog call`);
|
|
5502
|
+
}
|
|
5617
5503
|
return;
|
|
5618
5504
|
}
|
|
5619
5505
|
if (!options.dsn) {
|
|
5620
|
-
|
|
5506
|
+
if (isDebugBuild()) {
|
|
5507
|
+
logger.error(`Missing dsn option in showReportDialog call`);
|
|
5508
|
+
}
|
|
5621
5509
|
return;
|
|
5622
5510
|
}
|
|
5623
5511
|
const script = global$5.document.createElement('script');
|
|
5624
5512
|
script.async = true;
|
|
5625
|
-
script.src =
|
|
5513
|
+
script.src = getReportDialogEndpoint(options.dsn, options);
|
|
5626
5514
|
if (options.onLoad) {
|
|
5627
5515
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
5628
5516
|
script.onload = options.onLoad;
|
|
@@ -5642,10 +5530,14 @@ var Sentry = (function (exports) {
|
|
|
5642
5530
|
* @inheritDoc
|
|
5643
5531
|
*/
|
|
5644
5532
|
this.name = GlobalHandlers.id;
|
|
5645
|
-
/**
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5533
|
+
/**
|
|
5534
|
+
* Stores references functions to installing handlers. Will set to undefined
|
|
5535
|
+
* after they have been run so that they are not used twice.
|
|
5536
|
+
*/
|
|
5537
|
+
this._installFunc = {
|
|
5538
|
+
onerror: _installGlobalOnErrorHandler,
|
|
5539
|
+
onunhandledrejection: _installGlobalOnUnhandledRejectionHandler,
|
|
5540
|
+
};
|
|
5649
5541
|
this._options = Object.assign({ onerror: true, onunhandledrejection: true }, options);
|
|
5650
5542
|
}
|
|
5651
5543
|
/**
|
|
@@ -5653,176 +5545,182 @@ var Sentry = (function (exports) {
|
|
|
5653
5545
|
*/
|
|
5654
5546
|
setupOnce() {
|
|
5655
5547
|
Error.stackTraceLimit = 50;
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5548
|
+
const options = this._options;
|
|
5549
|
+
// We can disable guard-for-in as we construct the options object above + do checks against
|
|
5550
|
+
// `this._installFunc` for the property.
|
|
5551
|
+
// eslint-disable-next-line guard-for-in
|
|
5552
|
+
for (const key in options) {
|
|
5553
|
+
const installFunc = this._installFunc[key];
|
|
5554
|
+
if (installFunc && options[key]) {
|
|
5555
|
+
globalHandlerLog(key);
|
|
5556
|
+
installFunc();
|
|
5557
|
+
this._installFunc[key] = undefined;
|
|
5558
|
+
}
|
|
5663
5559
|
}
|
|
5664
5560
|
}
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5561
|
+
}
|
|
5562
|
+
/**
|
|
5563
|
+
* @inheritDoc
|
|
5564
|
+
*/
|
|
5565
|
+
GlobalHandlers.id = 'GlobalHandlers';
|
|
5566
|
+
/** JSDoc */
|
|
5567
|
+
function _installGlobalOnErrorHandler() {
|
|
5568
|
+
addInstrumentationHandler('error',
|
|
5569
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5570
|
+
(data) => {
|
|
5571
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5572
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5668
5573
|
return;
|
|
5669
5574
|
}
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
callback: (data) => {
|
|
5673
|
-
const error = data.error;
|
|
5674
|
-
const currentHub = getCurrentHub();
|
|
5675
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5676
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5677
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5678
|
-
return;
|
|
5679
|
-
}
|
|
5680
|
-
const client = currentHub.getClient();
|
|
5681
|
-
const event = error === undefined && isString(data.msg)
|
|
5682
|
-
? this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
|
|
5683
|
-
: this._enhanceEventWithInitialFrame(eventFromUnknownInput(error || data.msg, undefined, {
|
|
5684
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5685
|
-
rejection: false,
|
|
5686
|
-
}), data.url, data.line, data.column);
|
|
5687
|
-
addExceptionMechanism(event, {
|
|
5688
|
-
handled: false,
|
|
5689
|
-
type: 'onerror',
|
|
5690
|
-
});
|
|
5691
|
-
currentHub.captureEvent(event, {
|
|
5692
|
-
originalException: error,
|
|
5693
|
-
});
|
|
5694
|
-
},
|
|
5695
|
-
type: 'error',
|
|
5696
|
-
});
|
|
5697
|
-
this._onErrorHandlerInstalled = true;
|
|
5698
|
-
}
|
|
5699
|
-
/** JSDoc */
|
|
5700
|
-
_installGlobalOnUnhandledRejectionHandler() {
|
|
5701
|
-
if (this._onUnhandledRejectionHandlerInstalled) {
|
|
5575
|
+
const { msg, url, line, column, error } = data;
|
|
5576
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5702
5577
|
return;
|
|
5703
5578
|
}
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5717
|
-
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5718
|
-
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5719
|
-
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5720
|
-
else if ('detail' in e && 'reason' in e.detail) {
|
|
5721
|
-
error = e.detail.reason;
|
|
5722
|
-
}
|
|
5723
|
-
}
|
|
5724
|
-
catch (_oO) {
|
|
5725
|
-
// no-empty
|
|
5726
|
-
}
|
|
5727
|
-
const currentHub = getCurrentHub();
|
|
5728
|
-
const hasIntegration = currentHub.getIntegration(GlobalHandlers);
|
|
5729
|
-
const isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
|
|
5730
|
-
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
|
|
5731
|
-
return true;
|
|
5732
|
-
}
|
|
5733
|
-
const client = currentHub.getClient();
|
|
5734
|
-
const event = isPrimitive(error)
|
|
5735
|
-
? this._eventFromRejectionWithPrimitive(error)
|
|
5736
|
-
: eventFromUnknownInput(error, undefined, {
|
|
5737
|
-
attachStacktrace: client && client.getOptions().attachStacktrace,
|
|
5738
|
-
rejection: true,
|
|
5739
|
-
});
|
|
5740
|
-
event.level = exports.Severity.Error;
|
|
5741
|
-
addExceptionMechanism(event, {
|
|
5742
|
-
handled: false,
|
|
5743
|
-
type: 'onunhandledrejection',
|
|
5744
|
-
});
|
|
5745
|
-
currentHub.captureEvent(event, {
|
|
5746
|
-
originalException: error,
|
|
5747
|
-
});
|
|
5748
|
-
return;
|
|
5749
|
-
},
|
|
5750
|
-
type: 'unhandledrejection',
|
|
5751
|
-
});
|
|
5752
|
-
this._onUnhandledRejectionHandlerInstalled = true;
|
|
5753
|
-
}
|
|
5754
|
-
/**
|
|
5755
|
-
* This function creates a stack from an old, error-less onerror handler.
|
|
5756
|
-
*/
|
|
5757
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5758
|
-
_eventFromIncompleteOnError(msg, url, line, column) {
|
|
5759
|
-
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5760
|
-
// If 'message' is ErrorEvent, get real message from inside
|
|
5761
|
-
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5762
|
-
let name;
|
|
5763
|
-
const groups = message.match(ERROR_TYPES_RE);
|
|
5764
|
-
if (groups) {
|
|
5765
|
-
name = groups[1];
|
|
5766
|
-
message = groups[2];
|
|
5767
|
-
}
|
|
5768
|
-
const event = {
|
|
5769
|
-
exception: {
|
|
5770
|
-
values: [
|
|
5771
|
-
{
|
|
5772
|
-
type: name || 'Error',
|
|
5773
|
-
value: message,
|
|
5774
|
-
},
|
|
5775
|
-
],
|
|
5776
|
-
},
|
|
5777
|
-
};
|
|
5778
|
-
return this._enhanceEventWithInitialFrame(event, url, line, column);
|
|
5779
|
-
}
|
|
5780
|
-
/**
|
|
5781
|
-
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5782
|
-
*
|
|
5783
|
-
* @param reason: The `reason` property of the promise rejection
|
|
5784
|
-
* @returns An Event object with an appropriate `exception` value
|
|
5785
|
-
*/
|
|
5786
|
-
_eventFromRejectionWithPrimitive(reason) {
|
|
5787
|
-
return {
|
|
5788
|
-
exception: {
|
|
5789
|
-
values: [
|
|
5790
|
-
{
|
|
5791
|
-
type: 'UnhandledRejection',
|
|
5792
|
-
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5793
|
-
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5794
|
-
},
|
|
5795
|
-
],
|
|
5796
|
-
},
|
|
5797
|
-
};
|
|
5798
|
-
}
|
|
5799
|
-
/** JSDoc */
|
|
5579
|
+
const event = error === undefined && isString(msg)
|
|
5580
|
+
? _eventFromIncompleteOnError(msg, url, line, column)
|
|
5581
|
+
: _enhanceEventWithInitialFrame(eventFromUnknownInput(error || msg, undefined, {
|
|
5582
|
+
attachStacktrace,
|
|
5583
|
+
rejection: false,
|
|
5584
|
+
}), url, line, column);
|
|
5585
|
+
addMechanismAndCapture(hub, error, event, 'onerror');
|
|
5586
|
+
});
|
|
5587
|
+
}
|
|
5588
|
+
/** JSDoc */
|
|
5589
|
+
function _installGlobalOnUnhandledRejectionHandler() {
|
|
5590
|
+
addInstrumentationHandler('unhandledrejection',
|
|
5800
5591
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {};
|
|
5806
|
-
event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || [];
|
|
5807
|
-
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5808
|
-
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5809
|
-
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5810
|
-
if (event.exception.values[0].stacktrace.frames.length === 0) {
|
|
5811
|
-
event.exception.values[0].stacktrace.frames.push({
|
|
5812
|
-
colno,
|
|
5813
|
-
filename,
|
|
5814
|
-
function: '?',
|
|
5815
|
-
in_app: true,
|
|
5816
|
-
lineno,
|
|
5817
|
-
});
|
|
5592
|
+
(e) => {
|
|
5593
|
+
const [hub, attachStacktrace] = getHubAndAttachStacktrace();
|
|
5594
|
+
if (!hub.getIntegration(GlobalHandlers)) {
|
|
5595
|
+
return;
|
|
5818
5596
|
}
|
|
5819
|
-
|
|
5820
|
-
|
|
5597
|
+
let error = e;
|
|
5598
|
+
// dig the object of the rejection out of known event types
|
|
5599
|
+
try {
|
|
5600
|
+
// PromiseRejectionEvents store the object of the rejection under 'reason'
|
|
5601
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
|
|
5602
|
+
if ('reason' in e) {
|
|
5603
|
+
error = e.reason;
|
|
5604
|
+
}
|
|
5605
|
+
// something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
|
|
5606
|
+
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
|
|
5607
|
+
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
|
|
5608
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
|
|
5609
|
+
// https://github.com/getsentry/sentry-javascript/issues/2380
|
|
5610
|
+
else if ('detail' in e && 'reason' in e.detail) {
|
|
5611
|
+
error = e.detail.reason;
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
catch (_oO) {
|
|
5615
|
+
// no-empty
|
|
5616
|
+
}
|
|
5617
|
+
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
|
5618
|
+
return true;
|
|
5619
|
+
}
|
|
5620
|
+
const event = isPrimitive(error)
|
|
5621
|
+
? _eventFromRejectionWithPrimitive(error)
|
|
5622
|
+
: eventFromUnknownInput(error, undefined, {
|
|
5623
|
+
attachStacktrace,
|
|
5624
|
+
rejection: true,
|
|
5625
|
+
});
|
|
5626
|
+
event.level = 'error';
|
|
5627
|
+
addMechanismAndCapture(hub, error, event, 'onunhandledrejection');
|
|
5628
|
+
return;
|
|
5629
|
+
});
|
|
5821
5630
|
}
|
|
5822
5631
|
/**
|
|
5823
|
-
*
|
|
5632
|
+
* Create an event from a promise rejection where the `reason` is a primitive.
|
|
5633
|
+
*
|
|
5634
|
+
* @param reason: The `reason` property of the promise rejection
|
|
5635
|
+
* @returns An Event object with an appropriate `exception` value
|
|
5636
|
+
*/
|
|
5637
|
+
function _eventFromRejectionWithPrimitive(reason) {
|
|
5638
|
+
return {
|
|
5639
|
+
exception: {
|
|
5640
|
+
values: [
|
|
5641
|
+
{
|
|
5642
|
+
type: 'UnhandledRejection',
|
|
5643
|
+
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
|
|
5644
|
+
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
5645
|
+
},
|
|
5646
|
+
],
|
|
5647
|
+
},
|
|
5648
|
+
};
|
|
5649
|
+
}
|
|
5650
|
+
/**
|
|
5651
|
+
* This function creates a stack from an old, error-less onerror handler.
|
|
5824
5652
|
*/
|
|
5825
|
-
|
|
5653
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5654
|
+
function _eventFromIncompleteOnError(msg, url, line, column) {
|
|
5655
|
+
const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
5656
|
+
// If 'message' is ErrorEvent, get real message from inside
|
|
5657
|
+
let message = isErrorEvent(msg) ? msg.message : msg;
|
|
5658
|
+
let name = 'Error';
|
|
5659
|
+
const groups = message.match(ERROR_TYPES_RE);
|
|
5660
|
+
if (groups) {
|
|
5661
|
+
name = groups[1];
|
|
5662
|
+
message = groups[2];
|
|
5663
|
+
}
|
|
5664
|
+
const event = {
|
|
5665
|
+
exception: {
|
|
5666
|
+
values: [
|
|
5667
|
+
{
|
|
5668
|
+
type: name,
|
|
5669
|
+
value: message,
|
|
5670
|
+
},
|
|
5671
|
+
],
|
|
5672
|
+
},
|
|
5673
|
+
};
|
|
5674
|
+
return _enhanceEventWithInitialFrame(event, url, line, column);
|
|
5675
|
+
}
|
|
5676
|
+
/** JSDoc */
|
|
5677
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5678
|
+
function _enhanceEventWithInitialFrame(event, url, line, column) {
|
|
5679
|
+
// event.exception
|
|
5680
|
+
const e = (event.exception = event.exception || {});
|
|
5681
|
+
// event.exception.values
|
|
5682
|
+
const ev = (e.values = e.values || []);
|
|
5683
|
+
// event.exception.values[0]
|
|
5684
|
+
const ev0 = (ev[0] = ev[0] || {});
|
|
5685
|
+
// event.exception.values[0].stacktrace
|
|
5686
|
+
const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
|
|
5687
|
+
// event.exception.values[0].stacktrace.frames
|
|
5688
|
+
const ev0sf = (ev0s.frames = ev0s.frames || []);
|
|
5689
|
+
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
|
5690
|
+
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
|
5691
|
+
const filename = isString(url) && url.length > 0 ? url : getLocationHref();
|
|
5692
|
+
// event.exception.values[0].stacktrace.frames
|
|
5693
|
+
if (ev0sf.length === 0) {
|
|
5694
|
+
ev0sf.push({
|
|
5695
|
+
colno,
|
|
5696
|
+
filename,
|
|
5697
|
+
function: '?',
|
|
5698
|
+
in_app: true,
|
|
5699
|
+
lineno,
|
|
5700
|
+
});
|
|
5701
|
+
}
|
|
5702
|
+
return event;
|
|
5703
|
+
}
|
|
5704
|
+
function globalHandlerLog(type) {
|
|
5705
|
+
if (isDebugBuild()) {
|
|
5706
|
+
logger.log(`Global Handler attached: ${type}`);
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
function addMechanismAndCapture(hub, error, event, type) {
|
|
5710
|
+
addExceptionMechanism(event, {
|
|
5711
|
+
handled: false,
|
|
5712
|
+
type,
|
|
5713
|
+
});
|
|
5714
|
+
hub.captureEvent(event, {
|
|
5715
|
+
originalException: error,
|
|
5716
|
+
});
|
|
5717
|
+
}
|
|
5718
|
+
function getHubAndAttachStacktrace() {
|
|
5719
|
+
const hub = getCurrentHub();
|
|
5720
|
+
const client = hub.getClient();
|
|
5721
|
+
const attachStacktrace = client && client.getOptions().attachStacktrace;
|
|
5722
|
+
return [hub, attachStacktrace];
|
|
5723
|
+
}
|
|
5826
5724
|
|
|
5827
5725
|
const DEFAULT_EVENT_TARGET = [
|
|
5828
5726
|
'EventTarget',
|
|
@@ -5874,172 +5772,173 @@ var Sentry = (function (exports) {
|
|
|
5874
5772
|
setupOnce() {
|
|
5875
5773
|
const global = getGlobalObject();
|
|
5876
5774
|
if (this._options.setTimeout) {
|
|
5877
|
-
fill(global, 'setTimeout',
|
|
5775
|
+
fill(global, 'setTimeout', _wrapTimeFunction);
|
|
5878
5776
|
}
|
|
5879
5777
|
if (this._options.setInterval) {
|
|
5880
|
-
fill(global, 'setInterval',
|
|
5778
|
+
fill(global, 'setInterval', _wrapTimeFunction);
|
|
5881
5779
|
}
|
|
5882
5780
|
if (this._options.requestAnimationFrame) {
|
|
5883
|
-
fill(global, 'requestAnimationFrame',
|
|
5781
|
+
fill(global, 'requestAnimationFrame', _wrapRAF);
|
|
5884
5782
|
}
|
|
5885
5783
|
if (this._options.XMLHttpRequest && 'XMLHttpRequest' in global) {
|
|
5886
|
-
fill(XMLHttpRequest.prototype, 'send',
|
|
5784
|
+
fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
|
|
5887
5785
|
}
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
eventTarget.
|
|
5786
|
+
const eventTargetOption = this._options.eventTarget;
|
|
5787
|
+
if (eventTargetOption) {
|
|
5788
|
+
const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
|
|
5789
|
+
eventTarget.forEach(_wrapEventTarget);
|
|
5891
5790
|
}
|
|
5892
5791
|
}
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
data: { function: getFunctionName(original) },
|
|
5901
|
-
handled: true,
|
|
5902
|
-
type: 'instrument',
|
|
5903
|
-
},
|
|
5904
|
-
});
|
|
5905
|
-
return original.apply(this, args);
|
|
5906
|
-
};
|
|
5907
|
-
}
|
|
5908
|
-
/** JSDoc */
|
|
5792
|
+
}
|
|
5793
|
+
/**
|
|
5794
|
+
* @inheritDoc
|
|
5795
|
+
*/
|
|
5796
|
+
TryCatch.id = 'TryCatch';
|
|
5797
|
+
/** JSDoc */
|
|
5798
|
+
function _wrapTimeFunction(original) {
|
|
5909
5799
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
_wrapEventTarget(target) {
|
|
5928
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5929
|
-
const global = getGlobalObject();
|
|
5800
|
+
return function (...args) {
|
|
5801
|
+
const originalCallback = args[0];
|
|
5802
|
+
args[0] = wrap(originalCallback, {
|
|
5803
|
+
mechanism: {
|
|
5804
|
+
data: { function: getFunctionName(original) },
|
|
5805
|
+
handled: true,
|
|
5806
|
+
type: 'instrument',
|
|
5807
|
+
},
|
|
5808
|
+
});
|
|
5809
|
+
return original.apply(this, args);
|
|
5810
|
+
};
|
|
5811
|
+
}
|
|
5812
|
+
/** JSDoc */
|
|
5813
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5814
|
+
function _wrapRAF(original) {
|
|
5815
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5816
|
+
return function (callback) {
|
|
5930
5817
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
}
|
|
5953
|
-
catch (err) {
|
|
5954
|
-
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5955
|
-
}
|
|
5956
|
-
return original.call(this, eventName,
|
|
5818
|
+
return original.call(this, wrap(callback, {
|
|
5819
|
+
mechanism: {
|
|
5820
|
+
data: {
|
|
5821
|
+
function: 'requestAnimationFrame',
|
|
5822
|
+
handler: getFunctionName(original),
|
|
5823
|
+
},
|
|
5824
|
+
handled: true,
|
|
5825
|
+
type: 'instrument',
|
|
5826
|
+
},
|
|
5827
|
+
}));
|
|
5828
|
+
};
|
|
5829
|
+
}
|
|
5830
|
+
/** JSDoc */
|
|
5831
|
+
function _wrapXHR(originalSend) {
|
|
5832
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5833
|
+
return function (...args) {
|
|
5834
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
5835
|
+
const xhr = this;
|
|
5836
|
+
const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
|
|
5837
|
+
xmlHttpRequestProps.forEach(prop => {
|
|
5838
|
+
if (prop in xhr && typeof xhr[prop] === 'function') {
|
|
5957
5839
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5840
|
+
fill(xhr, prop, function (original) {
|
|
5841
|
+
const wrapOptions = {
|
|
5842
|
+
mechanism: {
|
|
5843
|
+
data: {
|
|
5844
|
+
function: prop,
|
|
5845
|
+
handler: getFunctionName(original),
|
|
5846
|
+
},
|
|
5847
|
+
handled: true,
|
|
5848
|
+
type: 'instrument',
|
|
5964
5849
|
},
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
});
|
|
5971
|
-
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5972
|
-
return function (eventName, fn, options) {
|
|
5973
|
-
var _a;
|
|
5974
|
-
/**
|
|
5975
|
-
* There are 2 possible scenarios here:
|
|
5976
|
-
*
|
|
5977
|
-
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5978
|
-
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5979
|
-
* as a pass-through, and call original `removeEventListener` with it.
|
|
5980
|
-
*
|
|
5981
|
-
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5982
|
-
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5983
|
-
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5984
|
-
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5985
|
-
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5986
|
-
*
|
|
5987
|
-
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5988
|
-
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5989
|
-
* to get rid of the initial handler and it'd stick there forever.
|
|
5990
|
-
*/
|
|
5991
|
-
const wrappedEventHandler = fn;
|
|
5992
|
-
try {
|
|
5993
|
-
const originalEventHandler = (_a = wrappedEventHandler) === null || _a === void 0 ? void 0 : _a.__sentry_wrapped__;
|
|
5994
|
-
if (originalEventHandler) {
|
|
5995
|
-
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5850
|
+
};
|
|
5851
|
+
// If Instrument integration has been called before TryCatch, get the name of original function
|
|
5852
|
+
const originalFunction = getOriginalFunction(original);
|
|
5853
|
+
if (originalFunction) {
|
|
5854
|
+
wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);
|
|
5996
5855
|
}
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
6002
|
-
};
|
|
5856
|
+
// Otherwise wrap directly
|
|
5857
|
+
return wrap(original, wrapOptions);
|
|
5858
|
+
});
|
|
5859
|
+
}
|
|
6003
5860
|
});
|
|
5861
|
+
return originalSend.apply(this, args);
|
|
5862
|
+
};
|
|
5863
|
+
}
|
|
5864
|
+
/** JSDoc */
|
|
5865
|
+
function _wrapEventTarget(target) {
|
|
5866
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5867
|
+
const global = getGlobalObject();
|
|
5868
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5869
|
+
const proto = global[target] && global[target].prototype;
|
|
5870
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
|
|
5871
|
+
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
|
|
5872
|
+
return;
|
|
6004
5873
|
}
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
fill(xhr, prop, function (original) {
|
|
6016
|
-
const wrapOptions = {
|
|
6017
|
-
mechanism: {
|
|
6018
|
-
data: {
|
|
6019
|
-
function: prop,
|
|
6020
|
-
handler: getFunctionName(original),
|
|
6021
|
-
},
|
|
6022
|
-
handled: true,
|
|
6023
|
-
type: 'instrument',
|
|
5874
|
+
fill(proto, 'addEventListener', function (original) {
|
|
5875
|
+
return function (eventName, fn, options) {
|
|
5876
|
+
try {
|
|
5877
|
+
if (typeof fn.handleEvent === 'function') {
|
|
5878
|
+
fn.handleEvent = wrap(fn.handleEvent.bind(fn), {
|
|
5879
|
+
mechanism: {
|
|
5880
|
+
data: {
|
|
5881
|
+
function: 'handleEvent',
|
|
5882
|
+
handler: getFunctionName(fn),
|
|
5883
|
+
target,
|
|
6024
5884
|
},
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
wrapOptions.mechanism.data.handler = getFunctionName(original.__sentry_original__);
|
|
6029
|
-
}
|
|
6030
|
-
// Otherwise wrap directly
|
|
6031
|
-
return wrap(original, wrapOptions);
|
|
5885
|
+
handled: true,
|
|
5886
|
+
type: 'instrument',
|
|
5887
|
+
},
|
|
6032
5888
|
});
|
|
6033
5889
|
}
|
|
6034
|
-
}
|
|
6035
|
-
|
|
5890
|
+
}
|
|
5891
|
+
catch (err) {
|
|
5892
|
+
// can sometimes get 'Permission denied to access property "handle Event'
|
|
5893
|
+
}
|
|
5894
|
+
return original.call(this, eventName,
|
|
5895
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5896
|
+
wrap(fn, {
|
|
5897
|
+
mechanism: {
|
|
5898
|
+
data: {
|
|
5899
|
+
function: 'addEventListener',
|
|
5900
|
+
handler: getFunctionName(fn),
|
|
5901
|
+
target,
|
|
5902
|
+
},
|
|
5903
|
+
handled: true,
|
|
5904
|
+
type: 'instrument',
|
|
5905
|
+
},
|
|
5906
|
+
}), options);
|
|
6036
5907
|
};
|
|
6037
|
-
}
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
5908
|
+
});
|
|
5909
|
+
fill(proto, 'removeEventListener', function (originalRemoveEventListener) {
|
|
5910
|
+
return function (eventName, fn, options) {
|
|
5911
|
+
/**
|
|
5912
|
+
* There are 2 possible scenarios here:
|
|
5913
|
+
*
|
|
5914
|
+
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
|
5915
|
+
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
|
5916
|
+
* as a pass-through, and call original `removeEventListener` with it.
|
|
5917
|
+
*
|
|
5918
|
+
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
|
5919
|
+
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
|
5920
|
+
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
|
5921
|
+
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
|
5922
|
+
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
|
5923
|
+
*
|
|
5924
|
+
* When someone adds a handler prior to initialization, and then do it again, but after,
|
|
5925
|
+
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
|
5926
|
+
* to get rid of the initial handler and it'd stick there forever.
|
|
5927
|
+
*/
|
|
5928
|
+
const wrappedEventHandler = fn;
|
|
5929
|
+
try {
|
|
5930
|
+
const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
|
|
5931
|
+
if (originalEventHandler) {
|
|
5932
|
+
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
catch (e) {
|
|
5936
|
+
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
|
|
5937
|
+
}
|
|
5938
|
+
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
|
5939
|
+
};
|
|
5940
|
+
});
|
|
5941
|
+
}
|
|
6043
5942
|
|
|
6044
5943
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
6045
5944
|
/**
|
|
@@ -6083,82 +5982,36 @@ var Sentry = (function (exports) {
|
|
|
6083
5982
|
*/
|
|
6084
5983
|
setupOnce() {
|
|
6085
5984
|
if (this._options.console) {
|
|
6086
|
-
addInstrumentationHandler(
|
|
6087
|
-
callback: (...args) => {
|
|
6088
|
-
this._consoleBreadcrumb(...args);
|
|
6089
|
-
},
|
|
6090
|
-
type: 'console',
|
|
6091
|
-
});
|
|
5985
|
+
addInstrumentationHandler('console', _consoleBreadcrumb);
|
|
6092
5986
|
}
|
|
6093
5987
|
if (this._options.dom) {
|
|
6094
|
-
addInstrumentationHandler(
|
|
6095
|
-
callback: (...args) => {
|
|
6096
|
-
this._domBreadcrumb(...args);
|
|
6097
|
-
},
|
|
6098
|
-
type: 'dom',
|
|
6099
|
-
});
|
|
5988
|
+
addInstrumentationHandler('dom', _domBreadcrumb(this._options.dom));
|
|
6100
5989
|
}
|
|
6101
5990
|
if (this._options.xhr) {
|
|
6102
|
-
addInstrumentationHandler(
|
|
6103
|
-
callback: (...args) => {
|
|
6104
|
-
this._xhrBreadcrumb(...args);
|
|
6105
|
-
},
|
|
6106
|
-
type: 'xhr',
|
|
6107
|
-
});
|
|
5991
|
+
addInstrumentationHandler('xhr', _xhrBreadcrumb);
|
|
6108
5992
|
}
|
|
6109
5993
|
if (this._options.fetch) {
|
|
6110
|
-
addInstrumentationHandler(
|
|
6111
|
-
callback: (...args) => {
|
|
6112
|
-
this._fetchBreadcrumb(...args);
|
|
6113
|
-
},
|
|
6114
|
-
type: 'fetch',
|
|
6115
|
-
});
|
|
5994
|
+
addInstrumentationHandler('fetch', _fetchBreadcrumb);
|
|
6116
5995
|
}
|
|
6117
5996
|
if (this._options.history) {
|
|
6118
|
-
addInstrumentationHandler(
|
|
6119
|
-
callback: (...args) => {
|
|
6120
|
-
this._historyBreadcrumb(...args);
|
|
6121
|
-
},
|
|
6122
|
-
type: 'history',
|
|
6123
|
-
});
|
|
5997
|
+
addInstrumentationHandler('history', _historyBreadcrumb);
|
|
6124
5998
|
}
|
|
6125
5999
|
}
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
level: exports.Severity.fromString(handlerData.level),
|
|
6138
|
-
message: safeJoin(handlerData.args, ' '),
|
|
6139
|
-
};
|
|
6140
|
-
if (handlerData.level === 'assert') {
|
|
6141
|
-
if (handlerData.args[0] === false) {
|
|
6142
|
-
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6143
|
-
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6144
|
-
}
|
|
6145
|
-
else {
|
|
6146
|
-
// Don't capture a breadcrumb for passed assertions
|
|
6147
|
-
return;
|
|
6148
|
-
}
|
|
6149
|
-
}
|
|
6150
|
-
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6151
|
-
input: handlerData.args,
|
|
6152
|
-
level: handlerData.level,
|
|
6153
|
-
});
|
|
6154
|
-
}
|
|
6155
|
-
/**
|
|
6156
|
-
* Creates breadcrumbs from DOM API calls
|
|
6157
|
-
*/
|
|
6000
|
+
}
|
|
6001
|
+
/**
|
|
6002
|
+
* @inheritDoc
|
|
6003
|
+
*/
|
|
6004
|
+
Breadcrumbs.id = 'Breadcrumbs';
|
|
6005
|
+
/**
|
|
6006
|
+
* A HOC that creaes a function that creates breadcrumbs from DOM API calls.
|
|
6007
|
+
* This is a HOC so that we get access to dom options in the closure.
|
|
6008
|
+
*/
|
|
6009
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6010
|
+
function _domBreadcrumb(dom) {
|
|
6158
6011
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6159
|
-
|
|
6012
|
+
function _innerDomBreadcrumb(handlerData) {
|
|
6160
6013
|
let target;
|
|
6161
|
-
let keyAttrs = typeof
|
|
6014
|
+
let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
|
|
6162
6015
|
if (typeof keyAttrs === 'string') {
|
|
6163
6016
|
keyAttrs = [keyAttrs];
|
|
6164
6017
|
}
|
|
@@ -6183,103 +6036,129 @@ var Sentry = (function (exports) {
|
|
|
6183
6036
|
global: handlerData.global,
|
|
6184
6037
|
});
|
|
6185
6038
|
}
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
xhr: handlerData.xhr,
|
|
6207
|
-
input: body,
|
|
6208
|
-
});
|
|
6209
|
-
return;
|
|
6210
|
-
}
|
|
6211
|
-
}
|
|
6212
|
-
/**
|
|
6213
|
-
* Creates breadcrumbs from fetch API calls
|
|
6214
|
-
*/
|
|
6215
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6216
|
-
_fetchBreadcrumb(handlerData) {
|
|
6217
|
-
// We only capture complete fetch requests
|
|
6218
|
-
if (!handlerData.endTimestamp) {
|
|
6219
|
-
return;
|
|
6220
|
-
}
|
|
6221
|
-
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6222
|
-
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6223
|
-
return;
|
|
6224
|
-
}
|
|
6225
|
-
if (handlerData.error) {
|
|
6226
|
-
getCurrentHub().addBreadcrumb({
|
|
6227
|
-
category: 'fetch',
|
|
6228
|
-
data: handlerData.fetchData,
|
|
6229
|
-
level: exports.Severity.Error,
|
|
6230
|
-
type: 'http',
|
|
6231
|
-
}, {
|
|
6232
|
-
data: handlerData.error,
|
|
6233
|
-
input: handlerData.args,
|
|
6234
|
-
});
|
|
6039
|
+
return _innerDomBreadcrumb;
|
|
6040
|
+
}
|
|
6041
|
+
/**
|
|
6042
|
+
* Creates breadcrumbs from console API calls
|
|
6043
|
+
*/
|
|
6044
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6045
|
+
function _consoleBreadcrumb(handlerData) {
|
|
6046
|
+
const breadcrumb = {
|
|
6047
|
+
category: 'console',
|
|
6048
|
+
data: {
|
|
6049
|
+
arguments: handlerData.args,
|
|
6050
|
+
logger: 'console',
|
|
6051
|
+
},
|
|
6052
|
+
level: severityFromString(handlerData.level),
|
|
6053
|
+
message: safeJoin(handlerData.args, ' '),
|
|
6054
|
+
};
|
|
6055
|
+
if (handlerData.level === 'assert') {
|
|
6056
|
+
if (handlerData.args[0] === false) {
|
|
6057
|
+
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
|
6058
|
+
breadcrumb.data.arguments = handlerData.args.slice(1);
|
|
6235
6059
|
}
|
|
6236
6060
|
else {
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6240
|
-
type: 'http',
|
|
6241
|
-
}, {
|
|
6242
|
-
input: handlerData.args,
|
|
6243
|
-
response: handlerData.response,
|
|
6244
|
-
});
|
|
6061
|
+
// Don't capture a breadcrumb for passed assertions
|
|
6062
|
+
return;
|
|
6245
6063
|
}
|
|
6246
6064
|
}
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
//
|
|
6259
|
-
if (
|
|
6260
|
-
|
|
6261
|
-
}
|
|
6262
|
-
// Use only the path component of the URL if the URL matches the current
|
|
6263
|
-
// document (almost all the time when using pushState)
|
|
6264
|
-
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6265
|
-
to = parsedTo.relative;
|
|
6266
|
-
}
|
|
6267
|
-
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6268
|
-
from = parsedFrom.relative;
|
|
6065
|
+
getCurrentHub().addBreadcrumb(breadcrumb, {
|
|
6066
|
+
input: handlerData.args,
|
|
6067
|
+
level: handlerData.level,
|
|
6068
|
+
});
|
|
6069
|
+
}
|
|
6070
|
+
/**
|
|
6071
|
+
* Creates breadcrumbs from XHR API calls
|
|
6072
|
+
*/
|
|
6073
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6074
|
+
function _xhrBreadcrumb(handlerData) {
|
|
6075
|
+
if (handlerData.endTimestamp) {
|
|
6076
|
+
// We only capture complete, non-sentry requests
|
|
6077
|
+
if (handlerData.xhr.__sentry_own_request__) {
|
|
6078
|
+
return;
|
|
6269
6079
|
}
|
|
6080
|
+
const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {};
|
|
6270
6081
|
getCurrentHub().addBreadcrumb({
|
|
6271
|
-
category: '
|
|
6082
|
+
category: 'xhr',
|
|
6272
6083
|
data: {
|
|
6273
|
-
|
|
6274
|
-
|
|
6084
|
+
method,
|
|
6085
|
+
url,
|
|
6086
|
+
status_code,
|
|
6275
6087
|
},
|
|
6088
|
+
type: 'http',
|
|
6089
|
+
}, {
|
|
6090
|
+
xhr: handlerData.xhr,
|
|
6091
|
+
input: body,
|
|
6276
6092
|
});
|
|
6093
|
+
return;
|
|
6277
6094
|
}
|
|
6278
6095
|
}
|
|
6279
6096
|
/**
|
|
6280
|
-
*
|
|
6097
|
+
* Creates breadcrumbs from fetch API calls
|
|
6098
|
+
*/
|
|
6099
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6100
|
+
function _fetchBreadcrumb(handlerData) {
|
|
6101
|
+
// We only capture complete fetch requests
|
|
6102
|
+
if (!handlerData.endTimestamp) {
|
|
6103
|
+
return;
|
|
6104
|
+
}
|
|
6105
|
+
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
|
6106
|
+
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
|
6107
|
+
return;
|
|
6108
|
+
}
|
|
6109
|
+
if (handlerData.error) {
|
|
6110
|
+
getCurrentHub().addBreadcrumb({
|
|
6111
|
+
category: 'fetch',
|
|
6112
|
+
data: handlerData.fetchData,
|
|
6113
|
+
level: 'error',
|
|
6114
|
+
type: 'http',
|
|
6115
|
+
}, {
|
|
6116
|
+
data: handlerData.error,
|
|
6117
|
+
input: handlerData.args,
|
|
6118
|
+
});
|
|
6119
|
+
}
|
|
6120
|
+
else {
|
|
6121
|
+
getCurrentHub().addBreadcrumb({
|
|
6122
|
+
category: 'fetch',
|
|
6123
|
+
data: Object.assign(Object.assign({}, handlerData.fetchData), { status_code: handlerData.response.status }),
|
|
6124
|
+
type: 'http',
|
|
6125
|
+
}, {
|
|
6126
|
+
input: handlerData.args,
|
|
6127
|
+
response: handlerData.response,
|
|
6128
|
+
});
|
|
6129
|
+
}
|
|
6130
|
+
}
|
|
6131
|
+
/**
|
|
6132
|
+
* Creates breadcrumbs from history API calls
|
|
6281
6133
|
*/
|
|
6282
|
-
|
|
6134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6135
|
+
function _historyBreadcrumb(handlerData) {
|
|
6136
|
+
const global = getGlobalObject();
|
|
6137
|
+
let from = handlerData.from;
|
|
6138
|
+
let to = handlerData.to;
|
|
6139
|
+
const parsedLoc = parseUrl(global.location.href);
|
|
6140
|
+
let parsedFrom = parseUrl(from);
|
|
6141
|
+
const parsedTo = parseUrl(to);
|
|
6142
|
+
// Initial pushState doesn't provide `from` information
|
|
6143
|
+
if (!parsedFrom.path) {
|
|
6144
|
+
parsedFrom = parsedLoc;
|
|
6145
|
+
}
|
|
6146
|
+
// Use only the path component of the URL if the URL matches the current
|
|
6147
|
+
// document (almost all the time when using pushState)
|
|
6148
|
+
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
|
6149
|
+
to = parsedTo.relative;
|
|
6150
|
+
}
|
|
6151
|
+
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
|
6152
|
+
from = parsedFrom.relative;
|
|
6153
|
+
}
|
|
6154
|
+
getCurrentHub().addBreadcrumb({
|
|
6155
|
+
category: 'navigation',
|
|
6156
|
+
data: {
|
|
6157
|
+
from,
|
|
6158
|
+
to,
|
|
6159
|
+
},
|
|
6160
|
+
});
|
|
6161
|
+
}
|
|
6283
6162
|
|
|
6284
6163
|
const DEFAULT_KEY = 'cause';
|
|
6285
6164
|
const DEFAULT_LIMIT = 5;
|
|
@@ -6302,40 +6181,36 @@ var Sentry = (function (exports) {
|
|
|
6302
6181
|
setupOnce() {
|
|
6303
6182
|
addGlobalEventProcessor((event, hint) => {
|
|
6304
6183
|
const self = getCurrentHub().getIntegration(LinkedErrors);
|
|
6305
|
-
|
|
6306
|
-
const handler = self._handler && self._handler.bind(self);
|
|
6307
|
-
return typeof handler === 'function' ? handler(event, hint) : event;
|
|
6308
|
-
}
|
|
6309
|
-
return event;
|
|
6184
|
+
return self ? _handler(self._key, self._limit, event, hint) : event;
|
|
6310
6185
|
});
|
|
6311
6186
|
}
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6187
|
+
}
|
|
6188
|
+
/**
|
|
6189
|
+
* @inheritDoc
|
|
6190
|
+
*/
|
|
6191
|
+
LinkedErrors.id = 'LinkedErrors';
|
|
6192
|
+
/**
|
|
6193
|
+
* @inheritDoc
|
|
6194
|
+
*/
|
|
6195
|
+
function _handler(key, limit, event, hint) {
|
|
6196
|
+
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
|
|
6321
6197
|
return event;
|
|
6322
6198
|
}
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
_walkErrorTree(error, key, stack = []) {
|
|
6327
|
-
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
|
|
6328
|
-
return stack;
|
|
6329
|
-
}
|
|
6330
|
-
const stacktrace = computeStackTrace(error[key]);
|
|
6331
|
-
const exception = exceptionFromStacktrace(stacktrace);
|
|
6332
|
-
return this._walkErrorTree(error[key], key, [exception, ...stack]);
|
|
6333
|
-
}
|
|
6199
|
+
const linkedErrors = _walkErrorTree(limit, hint.originalException, key);
|
|
6200
|
+
event.exception.values = [...linkedErrors, ...event.exception.values];
|
|
6201
|
+
return event;
|
|
6334
6202
|
}
|
|
6335
6203
|
/**
|
|
6336
|
-
*
|
|
6204
|
+
* JSDOC
|
|
6337
6205
|
*/
|
|
6338
|
-
|
|
6206
|
+
function _walkErrorTree(limit, error, key, stack = []) {
|
|
6207
|
+
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
|
|
6208
|
+
return stack;
|
|
6209
|
+
}
|
|
6210
|
+
const stacktrace = computeStackTrace(error[key]);
|
|
6211
|
+
const exception = exceptionFromStacktrace(stacktrace);
|
|
6212
|
+
return _walkErrorTree(limit, error[key], key, [exception, ...stack]);
|
|
6213
|
+
}
|
|
6339
6214
|
|
|
6340
6215
|
const global$6 = getGlobalObject();
|
|
6341
6216
|
/** UserAgent */
|
|
@@ -6351,17 +6226,16 @@ var Sentry = (function (exports) {
|
|
|
6351
6226
|
*/
|
|
6352
6227
|
setupOnce() {
|
|
6353
6228
|
addGlobalEventProcessor((event) => {
|
|
6354
|
-
var _a, _b, _c;
|
|
6355
6229
|
if (getCurrentHub().getIntegration(UserAgent)) {
|
|
6356
6230
|
// if none of the information we want exists, don't bother
|
|
6357
6231
|
if (!global$6.navigator && !global$6.location && !global$6.document) {
|
|
6358
6232
|
return event;
|
|
6359
6233
|
}
|
|
6360
6234
|
// grab as much info as exists and add it to the event
|
|
6361
|
-
const url = (
|
|
6235
|
+
const url = (event.request && event.request.url) || (global$6.location && global$6.location.href);
|
|
6362
6236
|
const { referrer } = global$6.document || {};
|
|
6363
6237
|
const { userAgent } = global$6.navigator || {};
|
|
6364
|
-
const headers = Object.assign(Object.assign(Object.assign({}, (
|
|
6238
|
+
const headers = Object.assign(Object.assign(Object.assign({}, (event.request && event.request.headers)), (referrer && { Referer: referrer })), (userAgent && { 'User-Agent': userAgent }));
|
|
6365
6239
|
const request = Object.assign(Object.assign({}, (url && { url })), { headers });
|
|
6366
6240
|
return Object.assign(Object.assign({}, event), { request });
|
|
6367
6241
|
}
|
|
@@ -6391,7 +6265,7 @@ var Sentry = (function (exports) {
|
|
|
6391
6265
|
if (self) {
|
|
6392
6266
|
// Juuust in case something goes wrong
|
|
6393
6267
|
try {
|
|
6394
|
-
if (
|
|
6268
|
+
if (_shouldDropEvent(currentEvent, self._previousEvent)) {
|
|
6395
6269
|
logger.warn(`Event dropped due to being a duplicate of previously captured event.`);
|
|
6396
6270
|
return null;
|
|
6397
6271
|
}
|
|
@@ -6404,139 +6278,139 @@ var Sentry = (function (exports) {
|
|
|
6404
6278
|
return currentEvent;
|
|
6405
6279
|
});
|
|
6406
6280
|
}
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
if (this._isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6416
|
-
return true;
|
|
6417
|
-
}
|
|
6281
|
+
}
|
|
6282
|
+
/**
|
|
6283
|
+
* @inheritDoc
|
|
6284
|
+
*/
|
|
6285
|
+
Dedupe.id = 'Dedupe';
|
|
6286
|
+
/** JSDoc */
|
|
6287
|
+
function _shouldDropEvent(currentEvent, previousEvent) {
|
|
6288
|
+
if (!previousEvent) {
|
|
6418
6289
|
return false;
|
|
6419
6290
|
}
|
|
6420
|
-
|
|
6421
|
-
_isSameMessageEvent(currentEvent, previousEvent) {
|
|
6422
|
-
const currentMessage = currentEvent.message;
|
|
6423
|
-
const previousMessage = previousEvent.message;
|
|
6424
|
-
// If neither event has a message property, they were both exceptions, so bail out
|
|
6425
|
-
if (!currentMessage && !previousMessage) {
|
|
6426
|
-
return false;
|
|
6427
|
-
}
|
|
6428
|
-
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6429
|
-
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6430
|
-
return false;
|
|
6431
|
-
}
|
|
6432
|
-
if (currentMessage !== previousMessage) {
|
|
6433
|
-
return false;
|
|
6434
|
-
}
|
|
6435
|
-
if (!this._isSameFingerprint(currentEvent, previousEvent)) {
|
|
6436
|
-
return false;
|
|
6437
|
-
}
|
|
6438
|
-
if (!this._isSameStacktrace(currentEvent, previousEvent)) {
|
|
6439
|
-
return false;
|
|
6440
|
-
}
|
|
6291
|
+
if (_isSameMessageEvent(currentEvent, previousEvent)) {
|
|
6441
6292
|
return true;
|
|
6442
6293
|
}
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
const exception = event.exception;
|
|
6446
|
-
if (exception) {
|
|
6447
|
-
try {
|
|
6448
|
-
// @ts-ignore Object could be undefined
|
|
6449
|
-
return exception.values[0].stacktrace.frames;
|
|
6450
|
-
}
|
|
6451
|
-
catch (_oO) {
|
|
6452
|
-
return undefined;
|
|
6453
|
-
}
|
|
6454
|
-
}
|
|
6455
|
-
else if (event.stacktrace) {
|
|
6456
|
-
return event.stacktrace.frames;
|
|
6457
|
-
}
|
|
6458
|
-
return undefined;
|
|
6294
|
+
if (_isSameExceptionEvent(currentEvent, previousEvent)) {
|
|
6295
|
+
return true;
|
|
6459
6296
|
}
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6297
|
+
return false;
|
|
6298
|
+
}
|
|
6299
|
+
/** JSDoc */
|
|
6300
|
+
function _isSameMessageEvent(currentEvent, previousEvent) {
|
|
6301
|
+
const currentMessage = currentEvent.message;
|
|
6302
|
+
const previousMessage = previousEvent.message;
|
|
6303
|
+
// If neither event has a message property, they were both exceptions, so bail out
|
|
6304
|
+
if (!currentMessage && !previousMessage) {
|
|
6305
|
+
return false;
|
|
6306
|
+
}
|
|
6307
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6308
|
+
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
|
6309
|
+
return false;
|
|
6310
|
+
}
|
|
6311
|
+
if (currentMessage !== previousMessage) {
|
|
6312
|
+
return false;
|
|
6313
|
+
}
|
|
6314
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6315
|
+
return false;
|
|
6316
|
+
}
|
|
6317
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6318
|
+
return false;
|
|
6319
|
+
}
|
|
6320
|
+
return true;
|
|
6321
|
+
}
|
|
6322
|
+
/** JSDoc */
|
|
6323
|
+
function _isSameExceptionEvent(currentEvent, previousEvent) {
|
|
6324
|
+
const previousException = _getExceptionFromEvent(previousEvent);
|
|
6325
|
+
const currentException = _getExceptionFromEvent(currentEvent);
|
|
6326
|
+
if (!previousException || !currentException) {
|
|
6327
|
+
return false;
|
|
6328
|
+
}
|
|
6329
|
+
if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
|
|
6330
|
+
return false;
|
|
6331
|
+
}
|
|
6332
|
+
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
|
6333
|
+
return false;
|
|
6334
|
+
}
|
|
6335
|
+
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
|
6336
|
+
return false;
|
|
6337
|
+
}
|
|
6338
|
+
return true;
|
|
6339
|
+
}
|
|
6340
|
+
/** JSDoc */
|
|
6341
|
+
function _isSameStacktrace(currentEvent, previousEvent) {
|
|
6342
|
+
let currentFrames = _getFramesFromEvent(currentEvent);
|
|
6343
|
+
let previousFrames = _getFramesFromEvent(previousEvent);
|
|
6344
|
+
// If neither event has a stacktrace, they are assumed to be the same
|
|
6345
|
+
if (!currentFrames && !previousFrames) {
|
|
6489
6346
|
return true;
|
|
6490
6347
|
}
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
return
|
|
6348
|
+
// If only one event has a stacktrace, but not the other one, they are not the same
|
|
6349
|
+
if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
|
|
6350
|
+
return false;
|
|
6494
6351
|
}
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
if (
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6352
|
+
currentFrames = currentFrames;
|
|
6353
|
+
previousFrames = previousFrames;
|
|
6354
|
+
// If number of frames differ, they are not the same
|
|
6355
|
+
if (previousFrames.length !== currentFrames.length) {
|
|
6356
|
+
return false;
|
|
6357
|
+
}
|
|
6358
|
+
// Otherwise, compare the two
|
|
6359
|
+
for (let i = 0; i < previousFrames.length; i++) {
|
|
6360
|
+
const frameA = previousFrames[i];
|
|
6361
|
+
const frameB = currentFrames[i];
|
|
6362
|
+
if (frameA.filename !== frameB.filename ||
|
|
6363
|
+
frameA.lineno !== frameB.lineno ||
|
|
6364
|
+
frameA.colno !== frameB.colno ||
|
|
6365
|
+
frameA.function !== frameB.function) {
|
|
6509
6366
|
return false;
|
|
6510
6367
|
}
|
|
6368
|
+
}
|
|
6369
|
+
return true;
|
|
6370
|
+
}
|
|
6371
|
+
/** JSDoc */
|
|
6372
|
+
function _isSameFingerprint(currentEvent, previousEvent) {
|
|
6373
|
+
let currentFingerprint = currentEvent.fingerprint;
|
|
6374
|
+
let previousFingerprint = previousEvent.fingerprint;
|
|
6375
|
+
// If neither event has a fingerprint, they are assumed to be the same
|
|
6376
|
+
if (!currentFingerprint && !previousFingerprint) {
|
|
6511
6377
|
return true;
|
|
6512
6378
|
}
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6379
|
+
// If only one event has a fingerprint, but not the other one, they are not the same
|
|
6380
|
+
if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
|
|
6381
|
+
return false;
|
|
6382
|
+
}
|
|
6383
|
+
currentFingerprint = currentFingerprint;
|
|
6384
|
+
previousFingerprint = previousFingerprint;
|
|
6385
|
+
// Otherwise, compare the two
|
|
6386
|
+
try {
|
|
6387
|
+
return !!(currentFingerprint.join('') === previousFingerprint.join(''));
|
|
6388
|
+
}
|
|
6389
|
+
catch (_oO) {
|
|
6390
|
+
return false;
|
|
6391
|
+
}
|
|
6392
|
+
}
|
|
6393
|
+
/** JSDoc */
|
|
6394
|
+
function _getExceptionFromEvent(event) {
|
|
6395
|
+
return event.exception && event.exception.values && event.exception.values[0];
|
|
6396
|
+
}
|
|
6397
|
+
/** JSDoc */
|
|
6398
|
+
function _getFramesFromEvent(event) {
|
|
6399
|
+
const exception = event.exception;
|
|
6400
|
+
if (exception) {
|
|
6528
6401
|
try {
|
|
6529
|
-
|
|
6402
|
+
// @ts-ignore Object could be undefined
|
|
6403
|
+
return exception.values[0].stacktrace.frames;
|
|
6530
6404
|
}
|
|
6531
6405
|
catch (_oO) {
|
|
6532
|
-
return
|
|
6406
|
+
return undefined;
|
|
6533
6407
|
}
|
|
6534
6408
|
}
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6409
|
+
else if (event.stacktrace) {
|
|
6410
|
+
return event.stacktrace.frames;
|
|
6411
|
+
}
|
|
6412
|
+
return undefined;
|
|
6413
|
+
}
|
|
6540
6414
|
|
|
6541
6415
|
|
|
6542
6416
|
|
|
@@ -6755,8 +6629,10 @@ var Sentry = (function (exports) {
|
|
|
6755
6629
|
if (client) {
|
|
6756
6630
|
return client.flush(timeout);
|
|
6757
6631
|
}
|
|
6758
|
-
|
|
6759
|
-
|
|
6632
|
+
if (isDebugBuild()) {
|
|
6633
|
+
logger.warn('Cannot flush events. No client defined.');
|
|
6634
|
+
}
|
|
6635
|
+
return resolvedSyncPromise(false);
|
|
6760
6636
|
}
|
|
6761
6637
|
/**
|
|
6762
6638
|
* Call `close()` on the current client, if there is one. See {@link Client.close}.
|
|
@@ -6771,8 +6647,10 @@ var Sentry = (function (exports) {
|
|
|
6771
6647
|
if (client) {
|
|
6772
6648
|
return client.close(timeout);
|
|
6773
6649
|
}
|
|
6774
|
-
|
|
6775
|
-
|
|
6650
|
+
if (isDebugBuild()) {
|
|
6651
|
+
logger.warn('Cannot flush events and disable SDK. No client defined.');
|
|
6652
|
+
}
|
|
6653
|
+
return resolvedSyncPromise(false);
|
|
6776
6654
|
}
|
|
6777
6655
|
/**
|
|
6778
6656
|
* Wrap code within a try/catch block so the SDK is able to capture errors.
|
|
@@ -6785,6 +6663,10 @@ var Sentry = (function (exports) {
|
|
|
6785
6663
|
function wrap$1(fn) {
|
|
6786
6664
|
return wrap(fn)();
|
|
6787
6665
|
}
|
|
6666
|
+
function startSessionOnHub(hub) {
|
|
6667
|
+
hub.startSession({ ignoreDuration: true });
|
|
6668
|
+
hub.captureSession();
|
|
6669
|
+
}
|
|
6788
6670
|
/**
|
|
6789
6671
|
* Enable automatic Session Tracking for the initial page load.
|
|
6790
6672
|
*/
|
|
@@ -6792,7 +6674,9 @@ var Sentry = (function (exports) {
|
|
|
6792
6674
|
const window = getGlobalObject();
|
|
6793
6675
|
const document = window.document;
|
|
6794
6676
|
if (typeof document === 'undefined') {
|
|
6795
|
-
|
|
6677
|
+
if (isDebugBuild()) {
|
|
6678
|
+
logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
|
|
6679
|
+
}
|
|
6796
6680
|
return;
|
|
6797
6681
|
}
|
|
6798
6682
|
const hub = getCurrentHub();
|
|
@@ -6802,26 +6686,20 @@ var Sentry = (function (exports) {
|
|
|
6802
6686
|
// https://github.com/getsentry/sentry-javascript/issues/3207 and
|
|
6803
6687
|
// https://github.com/getsentry/sentry-javascript/issues/3234 and
|
|
6804
6688
|
// https://github.com/getsentry/sentry-javascript/issues/3278.
|
|
6805
|
-
if (
|
|
6689
|
+
if (!hub.captureSession) {
|
|
6806
6690
|
return;
|
|
6807
6691
|
}
|
|
6808
6692
|
// The session duration for browser sessions does not track a meaningful
|
|
6809
6693
|
// concept that can be used as a metric.
|
|
6810
6694
|
// Automatically captured sessions are akin to page views, and thus we
|
|
6811
6695
|
// discard their duration.
|
|
6812
|
-
hub
|
|
6813
|
-
hub.captureSession();
|
|
6696
|
+
startSessionOnHub(hub);
|
|
6814
6697
|
// We want to create a session for every navigation as well
|
|
6815
|
-
addInstrumentationHandler({
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
}
|
|
6821
|
-
hub.startSession({ ignoreDuration: true });
|
|
6822
|
-
hub.captureSession();
|
|
6823
|
-
},
|
|
6824
|
-
type: 'history',
|
|
6698
|
+
addInstrumentationHandler('history', ({ from, to }) => {
|
|
6699
|
+
// Don't create an additional session for the initial route or if the location did not change
|
|
6700
|
+
if (!(from === undefined || from === to)) {
|
|
6701
|
+
startSessionOnHub(getCurrentHub());
|
|
6702
|
+
}
|
|
6825
6703
|
});
|
|
6826
6704
|
}
|
|
6827
6705
|
|