Newer
Older
249001
249002
249003
249004
249005
249006
249007
249008
249009
249010
249011
249012
249013
249014
249015
249016
249017
249018
249019
249020
249021
249022
249023
249024
249025
249026
249027
249028
249029
249030
249031
249032
249033
249034
249035
249036
249037
249038
249039
249040
249041
249042
249043
249044
249045
249046
249047
249048
249049
249050
249051
249052
249053
249054
249055
249056
249057
249058
249059
249060
249061
249062
249063
249064
249065
249066
249067
249068
249069
249070
249071
249072
249073
249074
249075
249076
249077
249078
249079
249080
249081
249082
249083
249084
249085
249086
249087
249088
249089
249090
249091
249092
249093
249094
249095
249096
249097
249098
249099
249100
249101
249102
249103
249104
249105
249106
249107
249108
249109
249110
249111
249112
249113
249114
249115
249116
249117
249118
249119
249120
249121
249122
249123
249124
249125
249126
249127
249128
249129
249130
249131
249132
249133
249134
249135
249136
249137
249138
249139
249140
249141
249142
249143
249144
249145
249146
249147
249148
249149
249150
249151
249152
249153
249154
249155
249156
249157
249158
249159
249160
249161
249162
249163
249164
249165
249166
249167
249168
249169
249170
249171
249172
249173
const keepSpan = span.startTimestamp < endTimestamp;
if (!keepSpan) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
_sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log(
'[Tracing] discarding Span since it happened after Transaction was finished',
JSON.stringify(span, undefined, 2),
);
}
return keepSpan;
});
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] flushing IdleTransaction');
} else {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] No active IdleTransaction');
}
// if `this._onScope` is `true`, the transaction put itself on the scope when it started
if (this._onScope) {
clearActiveTransaction(this._idleHub);
}
return super.finish(endTimestamp);
}
/**
* Register a callback function that gets excecuted before the transaction finishes.
* Useful for cleanup or if you want to add any additional spans based on current context.
*
* This is exposed because users have no other way of running something before an idle transaction
* finishes.
*/
registerBeforeFinishCallback(callback) {
this._beforeFinishCallbacks.push(callback);
}
/**
* @inheritDoc
*/
initSpanRecorder(maxlen) {
if (!this.spanRecorder) {
const pushActivity = (id) => {
if (this._finished) {
return;
}
this._pushActivity(id);
};
const popActivity = (id) => {
if (this._finished) {
return;
}
this._popActivity(id);
};
this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanId, maxlen);
// Start heartbeat so that transactions do not run forever.
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('Starting heartbeat');
this._pingHeartbeat();
}
this.spanRecorder.add(this);
}
/**
* Cancels the existing idletimeout, if there is one
*/
_cancelIdleTimeout() {
if (this._idleTimeoutID) {
clearTimeout(this._idleTimeoutID);
this._idleTimeoutID = undefined;
}
}
/**
* Creates an idletimeout
*/
_startIdleTimeout(endTimestamp) {
this._cancelIdleTimeout();
this._idleTimeoutID = setTimeout(() => {
if (!this._finished && Object.keys(this.activities).length === 0) {
this.finish(endTimestamp);
}
}, this._idleTimeout);
}
/**
* Start tracking a specific activity.
* @param spanId The span id that represents the activity
*/
_pushActivity(spanId) {
this._cancelIdleTimeout();
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log(`[Tracing] pushActivity: ${spanId}`);
this.activities[spanId] = true;
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
}
/**
* Remove an activity from usage
* @param spanId The span id that represents the activity
*/
_popActivity(spanId) {
if (this.activities[spanId]) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log(`[Tracing] popActivity ${spanId}`);
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.activities[spanId];
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
}
if (Object.keys(this.activities).length === 0) {
// We need to add the timeout here to have the real endtimestamp of the transaction
// Remember timestampWithMs is in seconds, timeout is in ms
const endTimestamp = (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_1__.timestampWithMs)() + this._idleTimeout / 1000;
this._startIdleTimeout(endTimestamp);
}
}
/**
* Checks when entries of this.activities are not changing for 3 beats.
* If this occurs we finish the transaction.
*/
_beat() {
// We should not be running heartbeat if the idle transaction is finished.
if (this._finished) {
return;
}
const heartbeatString = Object.keys(this.activities).join('');
if (heartbeatString === this._prevHeartbeatString) {
this._heartbeatCounter++;
} else {
this._heartbeatCounter = 1;
}
this._prevHeartbeatString = heartbeatString;
if (this._heartbeatCounter >= 3) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] Transaction finished because of no change for 3 heart beats');
this.setStatus('deadline_exceeded');
this.finish();
} else {
this._pingHeartbeat();
}
}
/**
* Pings the heartbeat
*/
_pingHeartbeat() {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`);
setTimeout(() => {
this._beat();
}, this._heartbeatInterval);
}
}
/**
* Reset transaction on scope to `undefined`
*/
function clearActiveTransaction(hub) {
const scope = hub.getScope();
if (scope) {
const transaction = scope.getTransaction();
if (transaction) {
scope.setSpan(undefined);
}
}
}
//# sourceMappingURL=idletransaction.js.map
/***/ }),
/* 1737 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "registerErrorInstrumentation": () => (/* binding */ registerErrorInstrumentation)
/* harmony export */ });
/* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1738);
/* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1653);
/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1733);
249185
249186
249187
249188
249189
249190
249191
249192
249193
249194
249195
249196
249197
249198
249199
249200
249201
249202
249203
249204
249205
249206
249207
249208
249209
249210
249211
249212
/**
* Configures global error listeners
*/
function registerErrorInstrumentation() {
(0,_sentry_utils__WEBPACK_IMPORTED_MODULE_0__.addInstrumentationHandler)('error', errorCallback);
(0,_sentry_utils__WEBPACK_IMPORTED_MODULE_0__.addInstrumentationHandler)('unhandledrejection', errorCallback);
}
/**
* If an error or unhandled promise occurs, we mark the active transaction as failed
*/
function errorCallback() {
const activeTransaction = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.getActiveTransaction)();
if (activeTransaction) {
const status = 'internal_error';
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_2__.logger.log(`[Tracing] Transaction: ${status} -> Global error occured`);
activeTransaction.setStatus(status);
}
}
//# sourceMappingURL=errors.js.map
/***/ }),
/* 1738 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "addInstrumentationHandler": () => (/* binding */ addInstrumentationHandler)
/* harmony export */ });
/* harmony import */ var _is_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1649);
/* harmony import */ var _logger_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1653);
/* harmony import */ var _object_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1650);
/* harmony import */ var _stacktrace_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1662);
/* harmony import */ var _supports_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1739);
/* harmony import */ var _worldwide_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1644);
249227
249228
249229
249230
249231
249232
249233
249234
249235
249236
249237
249238
249239
249240
249241
249242
249243
249244
249245
249246
249247
249248
249249
249250
249251
249252
249253
249254
249255
249256
249257
249258
249259
249260
249261
249262
249263
249264
249265
249266
249267
249268
249269
249270
249271
249272
249273
249274
249275
249276
249277
249278
249279
249280
249281
249282
249283
249284
249285
249286
249287
249288
249289
249290
249291
249292
249293
249294
249295
249296
249297
249298
249299
249300
249301
249302
249303
249304
249305
249306
249307
249308
249309
249310
249311
249312
249313
249314
249315
249316
249317
249318
249319
249320
249321
249322
249323
249324
249325
249326
249327
249328
249329
249330
249331
249332
249333
249334
249335
249336
249337
249338
249339
249340
249341
249342
249343
249344
249345
249346
249347
249348
249349
249350
249351
249352
249353
249354
249355
249356
249357
249358
249359
249360
249361
249362
249363
249364
249365
249366
249367
249368
249369
249370
249371
249372
249373
249374
249375
249376
249377
249378
249379
249380
249381
249382
249383
249384
249385
249386
249387
249388
249389
249390
249391
249392
249393
249394
249395
249396
249397
249398
249399
249400
249401
249402
249403
249404
249405
249406
249407
249408
249409
249410
249411
249412
249413
249414
249415
249416
249417
249418
249419
249420
249421
249422
249423
249424
249425
249426
249427
249428
249429
249430
249431
249432
249433
249434
249435
249436
249437
249438
249439
249440
249441
249442
249443
249444
249445
249446
249447
249448
249449
249450
249451
249452
249453
249454
249455
249456
249457
249458
249459
249460
249461
249462
249463
249464
249465
249466
249467
249468
249469
249470
249471
249472
249473
249474
249475
249476
249477
249478
249479
249480
249481
249482
249483
249484
249485
249486
249487
249488
249489
249490
249491
249492
249493
249494
249495
249496
249497
249498
249499
249500
249501
249502
249503
249504
249505
249506
249507
249508
249509
249510
249511
249512
249513
249514
249515
249516
249517
249518
249519
249520
249521
249522
249523
249524
249525
249526
249527
249528
249529
249530
249531
249532
249533
249534
249535
249536
249537
249538
249539
249540
249541
249542
249543
249544
249545
249546
249547
249548
249549
249550
249551
249552
249553
249554
249555
249556
249557
249558
249559
249560
249561
249562
249563
249564
249565
249566
249567
249568
249569
249570
249571
249572
249573
249574
249575
249576
249577
249578
249579
249580
249581
249582
249583
249584
249585
249586
249587
249588
249589
249590
249591
249592
249593
249594
249595
249596
249597
249598
249599
249600
249601
249602
249603
249604
249605
249606
249607
249608
249609
249610
249611
249612
249613
249614
249615
249616
249617
249618
249619
249620
249621
249622
249623
249624
249625
249626
249627
249628
249629
249630
249631
249632
249633
249634
249635
249636
249637
249638
249639
249640
249641
249642
249643
249644
249645
249646
249647
249648
249649
249650
249651
249652
249653
249654
249655
249656
249657
249658
249659
249660
249661
249662
249663
249664
249665
249666
249667
249668
249669
249670
249671
249672
249673
249674
249675
249676
249677
249678
249679
249680
249681
249682
249683
249684
249685
249686
249687
249688
249689
249690
249691
249692
249693
249694
249695
249696
249697
249698
249699
249700
249701
249702
249703
249704
249705
249706
249707
249708
249709
249710
249711
249712
249713
249714
249715
249716
249717
249718
249719
249720
249721
249722
249723
249724
249725
249726
249727
249728
249729
249730
249731
249732
249733
249734
249735
249736
249737
249738
249739
249740
249741
249742
249743
249744
249745
249746
249747
249748
249749
249750
249751
249752
249753
249754
249755
249756
249757
249758
249759
249760
249761
249762
249763
249764
249765
249766
249767
249768
249769
249770
249771
249772
249773
249774
249775
249776
249777
249778
249779
249780
249781
249782
249783
249784
249785
249786
249787
249788
249789
249790
249791
249792
249793
249794
249795
249796
249797
249798
249799
249800
249801
249802
249803
// eslint-disable-next-line deprecation/deprecation
const WINDOW = (0,_worldwide_js__WEBPACK_IMPORTED_MODULE_0__.getGlobalObject)();
/**
* Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc.
* - Console API
* - Fetch API
* - XHR API
* - History API
* - DOM API (click/typing)
* - Error API
* - UnhandledRejection API
*/
const handlers = {};
const instrumented = {};
/** Instruments given API */
function instrument(type) {
if (instrumented[type]) {
return;
}
instrumented[type] = true;
switch (type) {
case 'console':
instrumentConsole();
break;
case 'dom':
instrumentDOM();
break;
case 'xhr':
instrumentXHR();
break;
case 'fetch':
instrumentFetch();
break;
case 'history':
instrumentHistory();
break;
case 'error':
instrumentError();
break;
case 'unhandledrejection':
instrumentUnhandledRejection();
break;
default:
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _logger_js__WEBPACK_IMPORTED_MODULE_1__.logger.warn('unknown instrumentation type:', type);
return;
}
}
/**
* Add handler that will be called when given type of instrumentation triggers.
* Use at your own risk, this might break without changelog notice, only used internally.
* @hidden
*/
function addInstrumentationHandler(type, callback) {
handlers[type] = handlers[type] || [];
(handlers[type] ).push(callback);
instrument(type);
}
/** JSDoc */
function triggerHandlers(type, data) {
if (!type || !handlers[type]) {
return;
}
for (const handler of handlers[type] || []) {
try {
handler(data);
} catch (e) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
_logger_js__WEBPACK_IMPORTED_MODULE_1__.logger.error(
`Error while triggering instrumentation handler.\nType: ${type}\nName: ${(0,_stacktrace_js__WEBPACK_IMPORTED_MODULE_2__.getFunctionName)(handler)}\nError:`,
e,
);
}
}
}
/** JSDoc */
function instrumentConsole() {
if (!('console' in WINDOW)) {
return;
}
_logger_js__WEBPACK_IMPORTED_MODULE_1__.CONSOLE_LEVELS.forEach(function (level) {
if (!(level in WINDOW.console)) {
return;
}
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(WINDOW.console, level, function (originalConsoleMethod) {
return function (...args) {
triggerHandlers('console', { args, level });
// this fails for some browsers. :(
if (originalConsoleMethod) {
originalConsoleMethod.apply(WINDOW.console, args);
}
};
});
});
}
/** JSDoc */
function instrumentFetch() {
if (!(0,_supports_js__WEBPACK_IMPORTED_MODULE_4__.supportsNativeFetch)()) {
return;
}
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(WINDOW, 'fetch', function (originalFetch) {
return function (...args) {
const handlerData = {
args,
fetchData: {
method: getFetchMethod(args),
url: getFetchUrl(args),
},
startTimestamp: Date.now(),
};
triggerHandlers('fetch', {
...handlerData,
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return originalFetch.apply(WINDOW, args).then(
(response) => {
triggerHandlers('fetch', {
...handlerData,
endTimestamp: Date.now(),
response,
});
return response;
},
(error) => {
triggerHandlers('fetch', {
...handlerData,
endTimestamp: Date.now(),
error,
});
// NOTE: If you are a Sentry user, and you are seeing this stack frame,
// it means the sentry.javascript SDK caught an error invoking your application code.
// This is expected behavior and NOT indicative of a bug with sentry.javascript.
throw error;
},
);
};
});
}
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/** Extract `method` from fetch call arguments */
function getFetchMethod(fetchArgs = []) {
if ('Request' in WINDOW && (0,_is_js__WEBPACK_IMPORTED_MODULE_5__.isInstanceOf)(fetchArgs[0], Request) && fetchArgs[0].method) {
return String(fetchArgs[0].method).toUpperCase();
}
if (fetchArgs[1] && fetchArgs[1].method) {
return String(fetchArgs[1].method).toUpperCase();
}
return 'GET';
}
/** Extract `url` from fetch call arguments */
function getFetchUrl(fetchArgs = []) {
if (typeof fetchArgs[0] === 'string') {
return fetchArgs[0];
}
if ('Request' in WINDOW && (0,_is_js__WEBPACK_IMPORTED_MODULE_5__.isInstanceOf)(fetchArgs[0], Request)) {
return fetchArgs[0].url;
}
return String(fetchArgs[0]);
}
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
/** JSDoc */
function instrumentXHR() {
if (!('XMLHttpRequest' in WINDOW)) {
return;
}
const xhrproto = XMLHttpRequest.prototype;
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(xhrproto, 'open', function (originalOpen) {
return function ( ...args) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const xhr = this;
const url = args[1];
const xhrInfo = (xhr.__sentry_xhr__ = {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
method: (0,_is_js__WEBPACK_IMPORTED_MODULE_5__.isString)(args[0]) ? args[0].toUpperCase() : args[0],
url: args[1],
});
// if Sentry key appears in URL, don't capture it as a request
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if ((0,_is_js__WEBPACK_IMPORTED_MODULE_5__.isString)(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) {
xhr.__sentry_own_request__ = true;
}
const onreadystatechangeHandler = function () {
if (xhr.readyState === 4) {
try {
// touching statusCode in some platforms throws
// an exception
xhrInfo.status_code = xhr.status;
} catch (e) {
/* do nothing */
}
triggerHandlers('xhr', {
args,
endTimestamp: Date.now(),
startTimestamp: Date.now(),
xhr,
});
}
};
if ('onreadystatechange' in xhr && typeof xhr.onreadystatechange === 'function') {
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(xhr, 'onreadystatechange', function (original) {
return function (...readyStateArgs) {
onreadystatechangeHandler();
return original.apply(xhr, readyStateArgs);
};
});
} else {
xhr.addEventListener('readystatechange', onreadystatechangeHandler);
}
return originalOpen.apply(xhr, args);
};
});
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(xhrproto, 'send', function (originalSend) {
return function ( ...args) {
if (this.__sentry_xhr__ && args[0] !== undefined) {
this.__sentry_xhr__.body = args[0];
}
triggerHandlers('xhr', {
args,
startTimestamp: Date.now(),
xhr: this,
});
return originalSend.apply(this, args);
};
});
}
let lastHref;
/** JSDoc */
function instrumentHistory() {
if (!(0,_supports_js__WEBPACK_IMPORTED_MODULE_4__.supportsHistory)()) {
return;
}
const oldOnPopState = WINDOW.onpopstate;
WINDOW.onpopstate = function ( ...args) {
const to = WINDOW.location.href;
// keep track of the current URL state, as we always receive only the updated state
const from = lastHref;
lastHref = to;
triggerHandlers('history', {
from,
to,
});
if (oldOnPopState) {
// Apparently this can throw in Firefox when incorrectly implemented plugin is installed.
// https://github.com/getsentry/sentry-javascript/issues/3344
// https://github.com/bugsnag/bugsnag-js/issues/469
try {
return oldOnPopState.apply(this, args);
} catch (_oO) {
// no-empty
}
}
};
/** @hidden */
function historyReplacementFunction(originalHistoryFunction) {
return function ( ...args) {
const url = args.length > 2 ? args[2] : undefined;
if (url) {
// coerce to string (this is what pushState does)
const from = lastHref;
const to = String(url);
// keep track of the current URL state, as we always receive only the updated state
lastHref = to;
triggerHandlers('history', {
from,
to,
});
}
return originalHistoryFunction.apply(this, args);
};
}
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(WINDOW.history, 'pushState', historyReplacementFunction);
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(WINDOW.history, 'replaceState', historyReplacementFunction);
}
const debounceDuration = 1000;
let debounceTimerID;
let lastCapturedEvent;
/**
* Decide whether the current event should finish the debounce of previously captured one.
* @param previous previously captured event
* @param current event to be captured
*/
function shouldShortcircuitPreviousDebounce(previous, current) {
// If there was no previous event, it should always be swapped for the new one.
if (!previous) {
return true;
}
// If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.
if (previous.type !== current.type) {
return true;
}
try {
// If both events have the same type, it's still possible that actions were performed on different targets.
// e.g. 2 clicks on different buttons.
if (previous.target !== current.target) {
return true;
}
} catch (e) {
// just accessing `target` property can throw an exception in some rare circumstances
// see: https://github.com/getsentry/sentry-javascript/issues/838
}
// If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_
// to which an event listener was attached), we treat them as the same action, as we want to capture
// only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.
return false;
}
/**
* Decide whether an event should be captured.
* @param event event to be captured
*/
function shouldSkipDOMEvent(event) {
// We are only interested in filtering `keypress` events for now.
if (event.type !== 'keypress') {
return false;
}
try {
const target = event.target ;
if (!target || !target.tagName) {
return true;
}
// Only consider keypress events on actual input elements. This will disregard keypresses targeting body
// e.g.tabbing through elements, hotkeys, etc.
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
return false;
}
} catch (e) {
// just accessing `target` property can throw an exception in some rare circumstances
// see: https://github.com/getsentry/sentry-javascript/issues/838
}
return true;
}
/**
* Wraps addEventListener to capture UI breadcrumbs
* @param handler function that will be triggered
* @param globalListener indicates whether event was captured by the global event listener
* @returns wrapped breadcrumb events handler
* @hidden
*/
function makeDOMEventHandler(handler, globalListener = false) {
return (event) => {
// It's possible this handler might trigger multiple times for the same
// event (e.g. event propagation through node ancestors).
// Ignore if we've already captured that event.
if (!event || lastCapturedEvent === event) {
return;
}
// We always want to skip _some_ events.
if (shouldSkipDOMEvent(event)) {
return;
}
const name = event.type === 'keypress' ? 'input' : event.type;
// If there is no debounce timer, it means that we can safely capture the new event and store it for future comparisons.
if (debounceTimerID === undefined) {
handler({
event: event,
name,
global: globalListener,
});
lastCapturedEvent = event;
}
// If there is a debounce awaiting, see if the new event is different enough to treat it as a unique one.
// If that's the case, emit the previous event and store locally the newly-captured DOM event.
else if (shouldShortcircuitPreviousDebounce(lastCapturedEvent, event)) {
handler({
event: event,
name,
global: globalListener,
});
lastCapturedEvent = event;
}
// Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.
clearTimeout(debounceTimerID);
debounceTimerID = WINDOW.setTimeout(() => {
debounceTimerID = undefined;
}, debounceDuration);
};
}
/** JSDoc */
function instrumentDOM() {
if (!('document' in WINDOW)) {
return;
}
// Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom
// handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before
// we instrument `addEventListener` so that we don't end up attaching this handler twice.
const triggerDOMHandler = triggerHandlers.bind(null, 'dom');
const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);
WINDOW.document.addEventListener('click', globalDOMEventHandler, false);
WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);
// After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled
// clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That
// way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler
// could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still
// guaranteed to fire at least once.)
['EventTarget', 'Node'].forEach((target) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const proto = (WINDOW )[target] && (WINDOW )[target].prototype;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
return;
}
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(proto, 'addEventListener', function (originalAddEventListener) {
return function (
type,
listener,
options,
) {
if (type === 'click' || type == 'keypress') {
try {
const el = this ;
const handlers = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {});
const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });
if (!handlerForType.handler) {
const handler = makeDOMEventHandler(triggerDOMHandler);
handlerForType.handler = handler;
originalAddEventListener.call(this, type, handler, options);
}
handlerForType.refCount++;
} catch (e) {
// Accessing dom properties is always fragile.
// Also allows us to skip `addEventListenrs` calls with no proper `this` context.
}
}
return originalAddEventListener.call(this, type, listener, options);
};
});
(0,_object_js__WEBPACK_IMPORTED_MODULE_3__.fill)(
proto,
'removeEventListener',
function (originalRemoveEventListener) {
return function (
type,
listener,
options,
) {
if (type === 'click' || type == 'keypress') {
try {
const el = this ;
const handlers = el.__sentry_instrumentation_handlers__ || {};
const handlerForType = handlers[type];
if (handlerForType) {
handlerForType.refCount--;
// If there are no longer any custom handlers of the current type on this element, we can remove ours, too.
if (handlerForType.refCount <= 0) {
originalRemoveEventListener.call(this, type, handlerForType.handler, options);
handlerForType.handler = undefined;
delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
}
// If there are no longer any custom handlers of any type on this element, cleanup everything.
if (Object.keys(handlers).length === 0) {
delete el.__sentry_instrumentation_handlers__;
}
}
} catch (e) {
// Accessing dom properties is always fragile.
// Also allows us to skip `addEventListenrs` calls with no proper `this` context.
}
}
return originalRemoveEventListener.call(this, type, listener, options);
};
},
);
});
}
let _oldOnErrorHandler = null;
/** JSDoc */
function instrumentError() {
_oldOnErrorHandler = WINDOW.onerror;
WINDOW.onerror = function (msg, url, line, column, error) {
triggerHandlers('error', {
column,
error,
line,
msg,
url,
});
if (_oldOnErrorHandler) {
// eslint-disable-next-line prefer-rest-params
return _oldOnErrorHandler.apply(this, arguments);
}
return false;
};
}
let _oldOnUnhandledRejectionHandler = null;
/** JSDoc */
function instrumentUnhandledRejection() {
_oldOnUnhandledRejectionHandler = WINDOW.onunhandledrejection;
WINDOW.onunhandledrejection = function (e) {
triggerHandlers('unhandledrejection', e);
if (_oldOnUnhandledRejectionHandler) {
// eslint-disable-next-line prefer-rest-params
return _oldOnUnhandledRejectionHandler.apply(this, arguments);
}
return true;
};
}
//# sourceMappingURL=instrument.js.map
/***/ }),
/* 1739 */
249805
249806
249807
249808
249809
249810
249811
249812
249813
249814
249815
249816
249817
249818
249819
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "isNativeFetch": () => (/* binding */ isNativeFetch),
/* harmony export */ "supportsDOMError": () => (/* binding */ supportsDOMError),
/* harmony export */ "supportsDOMException": () => (/* binding */ supportsDOMException),
/* harmony export */ "supportsErrorEvent": () => (/* binding */ supportsErrorEvent),
/* harmony export */ "supportsFetch": () => (/* binding */ supportsFetch),
/* harmony export */ "supportsHistory": () => (/* binding */ supportsHistory),
/* harmony export */ "supportsNativeFetch": () => (/* binding */ supportsNativeFetch),
/* harmony export */ "supportsReferrerPolicy": () => (/* binding */ supportsReferrerPolicy),
/* harmony export */ "supportsReportingObserver": () => (/* binding */ supportsReportingObserver)
/* harmony export */ });
/* harmony import */ var _logger_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1653);
/* harmony import */ var _worldwide_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1644);
249822
249823
249824
249825
249826
249827
249828
249829
249830
249831
249832
249833
249834
249835
249836
249837
249838
249839
249840
249841
249842
249843
249844
249845
249846
249847
249848
249849
249850
249851
249852
249853
249854
249855
249856
249857
249858
249859
249860
249861
249862
249863
249864
249865
249866
249867
249868
249869
249870
249871
249872
249873
249874
249875
249876
249877
249878
249879
249880
249881
249882
249883
249884
249885
249886
249887
249888
249889
249890
249891
249892
249893
249894
249895
249896
249897
249898
249899
249900
249901
249902
249903
249904
249905
249906
249907
249908
249909
249910
249911
249912
249913
249914
249915
249916
249917
249918
249919
249920
249921
249922
249923
249924
249925
249926
249927
249928
249929
249930
249931
249932
249933
249934
249935
249936
249937
249938
249939
249940
249941
249942
249943
249944
249945
249946
249947
249948
249949
249950
249951
249952
249953
249954
249955
249956
249957
249958
249959
249960
249961
249962
249963
249964
249965
249966
249967
249968
249969
249970
249971
249972
249973
249974
249975
249976
249977
249978
249979
249980
249981
249982
249983
249984
249985
249986
249987
249988
249989
249990
249991
249992
249993
249994
249995
249996
249997
249998
249999
250000
// eslint-disable-next-line deprecation/deprecation
const WINDOW = (0,_worldwide_js__WEBPACK_IMPORTED_MODULE_0__.getGlobalObject)();
/**
* Tells whether current environment supports ErrorEvent objects
* {@link supportsErrorEvent}.
*
* @returns Answer to the given question.
*/
function supportsErrorEvent() {
try {
new ErrorEvent('');
return true;
} catch (e) {
return false;
}
}
/**
* Tells whether current environment supports DOMError objects
* {@link supportsDOMError}.
*
* @returns Answer to the given question.
*/
function supportsDOMError() {
try {
// Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError':
// 1 argument required, but only 0 present.
// @ts-ignore It really needs 1 argument, not 0.
new DOMError('');
return true;
} catch (e) {
return false;
}
}
/**
* Tells whether current environment supports DOMException objects
* {@link supportsDOMException}.
*
* @returns Answer to the given question.
*/
function supportsDOMException() {
try {
new DOMException('');
return true;
} catch (e) {
return false;
}
}
/**
* Tells whether current environment supports Fetch API
* {@link supportsFetch}.
*
* @returns Answer to the given question.
*/
function supportsFetch() {
if (!('fetch' in WINDOW)) {
return false;
}
try {
new Headers();
new Request('http://www.example.com');
new Response();
return true;
} catch (e) {
return false;
}
}
/**
* isNativeFetch checks if the given function is a native implementation of fetch()
*/
// eslint-disable-next-line @typescript-eslint/ban-types
function isNativeFetch(func) {
return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString());
}
/**
* Tells whether current environment supports Fetch API natively
* {@link supportsNativeFetch}.
*
* @returns true if `window.fetch` is natively implemented, false otherwise
*/
function supportsNativeFetch() {
if (!supportsFetch()) {
return false;
}
// Fast path to avoid DOM I/O
// eslint-disable-next-line @typescript-eslint/unbound-method
if (isNativeFetch(WINDOW.fetch)) {
return true;
}
// window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
// so create a "pure" iframe to see if that has native fetch
let result = false;
const doc = WINDOW.document;
// eslint-disable-next-line deprecation/deprecation
if (doc && typeof (doc.createElement ) === 'function') {
try {
const sandbox = doc.createElement('iframe');
sandbox.hidden = true;
doc.head.appendChild(sandbox);
if (sandbox.contentWindow && sandbox.contentWindow.fetch) {
// eslint-disable-next-line @typescript-eslint/unbound-method
result = isNativeFetch(sandbox.contentWindow.fetch);
}
doc.head.removeChild(sandbox);
} catch (err) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
_logger_js__WEBPACK_IMPORTED_MODULE_1__.logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
}
}
return result;
}
/**
* Tells whether current environment supports ReportingObserver API
* {@link supportsReportingObserver}.
*
* @returns Answer to the given question.
*/
function supportsReportingObserver() {
return 'ReportingObserver' in WINDOW;
}
/**
* Tells whether current environment supports Referrer Policy API
* {@link supportsReferrerPolicy}.
*
* @returns Answer to the given question.
*/
function supportsReferrerPolicy() {
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
// (see https://caniuse.com/#feat=referrer-policy),
// it doesn't. And it throws an exception instead of ignoring this parameter...
// REF: https://github.com/getsentry/raven-js/issues/1233
if (!supportsFetch()) {
return false;
}
try {
new Request('_', {
referrerPolicy: 'origin' ,
});
return true;
} catch (e) {
return false;
}
}
/**
* Tells whether current environment supports History API
* {@link supportsHistory}.
*
* @returns Answer to the given question.
*/
function supportsHistory() {
// NOTE: in Chrome App environment, touching history.pushState, *even inside
// a try/catch block*, will cause Chrome to output an error to console.error
// borrowed from: https://github.com/angular/angular.js/pull/13945/files
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const chrome = (WINDOW ).chrome;
const isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState;
return !isChromePackagedApp && hasHistoryApi;
}