Skip to content
Snippets Groups Projects
index.js 8.95 MiB
Newer Older
  • Learn to ignore specific revisions
  •    toTraceparent() {
        let sampledString = '';
        if (this.sampled !== undefined) {
          sampledString = this.sampled ? '-1' : '-0';
        }
        return `${this.traceId}-${this.spanId}${sampledString}`;
      }
    
      /**
       * @inheritDoc
       */
       toContext() {
        return (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_3__.dropUndefinedKeys)({
          data: this.data,
          description: this.description,
          endTimestamp: this.endTimestamp,
          op: this.op,
          parentSpanId: this.parentSpanId,
          sampled: this.sampled,
          spanId: this.spanId,
          startTimestamp: this.startTimestamp,
          status: this.status,
          tags: this.tags,
          traceId: this.traceId,
        });
      }
    
      /**
       * @inheritDoc
       */
       updateWithContext(spanContext) {
        this.data = (0,_sentry_utils_esm_buildPolyfills__WEBPACK_IMPORTED_MODULE_4__._nullishCoalesce)(spanContext.data, () => ( {}));
        this.description = spanContext.description;
        this.endTimestamp = spanContext.endTimestamp;
        this.op = spanContext.op;
        this.parentSpanId = spanContext.parentSpanId;
        this.sampled = spanContext.sampled;
        this.spanId = (0,_sentry_utils_esm_buildPolyfills__WEBPACK_IMPORTED_MODULE_4__._nullishCoalesce)(spanContext.spanId, () => ( this.spanId));
        this.startTimestamp = (0,_sentry_utils_esm_buildPolyfills__WEBPACK_IMPORTED_MODULE_4__._nullishCoalesce)(spanContext.startTimestamp, () => ( this.startTimestamp));
        this.status = spanContext.status;
        this.tags = (0,_sentry_utils_esm_buildPolyfills__WEBPACK_IMPORTED_MODULE_4__._nullishCoalesce)(spanContext.tags, () => ( {}));
        this.traceId = (0,_sentry_utils_esm_buildPolyfills__WEBPACK_IMPORTED_MODULE_4__._nullishCoalesce)(spanContext.traceId, () => ( this.traceId));
    
        return this;
      }
    
      /**
       * @inheritDoc
       */
       getTraceContext()
    
     {
        return (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_3__.dropUndefinedKeys)({
          data: Object.keys(this.data).length > 0 ? this.data : undefined,
          description: this.description,
          op: this.op,
          parent_span_id: this.parentSpanId,
          span_id: this.spanId,
          status: this.status,
          tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
          trace_id: this.traceId,
        });
      }
    
      /**
       * @inheritDoc
       */
       toJSON()
    
     {
        return (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_3__.dropUndefinedKeys)({
          data: Object.keys(this.data).length > 0 ? this.data : undefined,
          description: this.description,
          op: this.op,
          parent_span_id: this.parentSpanId,
          span_id: this.spanId,
          start_timestamp: this.startTimestamp,
          status: this.status,
          tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
          timestamp: this.endTimestamp,
          trace_id: this.traceId,
        });
      }
    }
    
    /**
     * Converts a HTTP status code into a {@link SpanStatusType}.
     *
     * @param httpStatus The HTTP response status code.
     * @returns The span status or unknown_error.
     */
    function spanStatusfromHttpCode(httpStatus) {
      if (httpStatus < 400 && httpStatus >= 100) {
        return 'ok';
      }
    
      if (httpStatus >= 400 && httpStatus < 500) {
        switch (httpStatus) {
          case 401:
            return 'unauthenticated';
          case 403:
            return 'permission_denied';
          case 404:
            return 'not_found';
          case 409:
            return 'already_exists';
          case 413:
            return 'failed_precondition';
          case 429:
            return 'resource_exhausted';
          default:
            return 'invalid_argument';
        }
      }
    
      if (httpStatus >= 500 && httpStatus < 600) {
        switch (httpStatus) {
          case 501:
            return 'unimplemented';
          case 503:
            return 'unavailable';
          case 504:
            return 'deadline_exceeded';
          default:
            return 'internal_error';
        }
      }
    
      return 'unknown_error';
    }
    
    
    //# sourceMappingURL=span.js.map
    
    
    /***/ }),
    
    /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    
    
    "use strict";
    __webpack_require__.r(__webpack_exports__);
    
    /* harmony export */ __webpack_require__.d(__webpack_exports__, {
    /* harmony export */   "DEFAULT_FINAL_TIMEOUT": () => (/* binding */ DEFAULT_FINAL_TIMEOUT),
    /* harmony export */   "DEFAULT_HEARTBEAT_INTERVAL": () => (/* binding */ DEFAULT_HEARTBEAT_INTERVAL),
    /* harmony export */   "DEFAULT_IDLE_TIMEOUT": () => (/* binding */ DEFAULT_IDLE_TIMEOUT),
    /* harmony export */   "IdleTransaction": () => (/* binding */ IdleTransaction),
    /* harmony export */   "IdleTransactionSpanRecorder": () => (/* binding */ IdleTransactionSpanRecorder)
    /* harmony export */ });
    
    /* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1538);
    /* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1548);
    /* harmony import */ var _span_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1613);
    /* harmony import */ var _transaction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1612);
    
    
    
    
    
    const DEFAULT_IDLE_TIMEOUT = 1000;
    const DEFAULT_FINAL_TIMEOUT = 30000;
    const DEFAULT_HEARTBEAT_INTERVAL = 5000;
    
    /**
     * @inheritDoc
     */
    
    class IdleTransactionSpanRecorder extends _span_js__WEBPACK_IMPORTED_MODULE_0__.SpanRecorder {
    
       constructor(
          _pushActivity,
          _popActivity,
         transactionSpanId,
        maxlen,
      ) {
        super(maxlen);this._pushActivity = _pushActivity;this._popActivity = _popActivity;this.transactionSpanId = transactionSpanId;;
      }
    
      /**
       * @inheritDoc
       */
       add(span) {
        // We should make sure we do not push and pop activities for
        // the transaction that this span recorder belongs to.
        if (span.spanId !== this.transactionSpanId) {
          // We patch span.finish() to pop an activity after setting an endTimestamp.
          span.finish = (endTimestamp) => {
    
            span.endTimestamp = typeof endTimestamp === 'number' ? endTimestamp : (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_1__.timestampWithMs)();
    
            this._popActivity(span.spanId);
          };
    
          // We should only push new activities if the span does not have an end timestamp.
          if (span.endTimestamp === undefined) {
            this._pushActivity(span.spanId);
          }
        }
    
        super.add(span);
      }
    }
    
    /**
     * An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities.
     * You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will
     * put itself on the scope on creation.
     */
    
    class IdleTransaction extends _transaction_js__WEBPACK_IMPORTED_MODULE_2__.Transaction {
    
      // Activities store a list of active spans
       __init() {this.activities = {};}
    
      // Track state of activities in previous heartbeat
    
      // Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats.
       __init2() {this._heartbeatCounter = 0;}
    
      // We should not use heartbeat if we finished a transaction
       __init3() {this._finished = false;}
    
        __init4() {this._beforeFinishCallbacks = [];}
    
      /**
       * Timer that tracks Transaction idleTimeout
       */
    
       constructor(
        transactionContext,
          _idleHub,
        /**
         * The time to wait in ms until the idle transaction will be finished. This timer is started each time
         * there are no active spans on this transaction.
         */
          _idleTimeout = DEFAULT_IDLE_TIMEOUT,
        /**
         * The final value in ms that a transaction cannot exceed
         */
          _finalTimeout = DEFAULT_FINAL_TIMEOUT,
          _heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,
        // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends
          _onScope = false,
      ) {
        super(transactionContext, _idleHub);this._idleHub = _idleHub;this._idleTimeout = _idleTimeout;this._finalTimeout = _finalTimeout;this._heartbeatInterval = _heartbeatInterval;this._onScope = _onScope;IdleTransaction.prototype.__init.call(this);IdleTransaction.prototype.__init2.call(this);IdleTransaction.prototype.__init3.call(this);IdleTransaction.prototype.__init4.call(this);;
    
        if (_onScope) {
          // There should only be one active transaction on the scope
          clearActiveTransaction(_idleHub);
    
          // We set the transaction here on the scope so error events pick up the trace
          // context and attach it to the error.
    
          (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log(`Setting idle transaction on scope. Span ID: ${this.spanId}`);
    
          _idleHub.configureScope(scope => scope.setSpan(this));
        }
    
        this._startIdleTimeout();
        setTimeout(() => {
          if (!this._finished) {
            this.setStatus('deadline_exceeded');
            this.finish();
          }
        }, this._finalTimeout);
      }
    
      /** {@inheritDoc} */
    
       finish(endTimestamp = (0,_sentry_utils__WEBPACK_IMPORTED_MODULE_1__.timestampWithMs)()) {
    
        this._finished = true;
        this.activities = {};
    
        if (this.spanRecorder) {
          (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
    
            _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString(), this.op);
    
    
          for (const callback of this._beforeFinishCallbacks) {
            callback(this, endTimestamp);
          }
    
          this.spanRecorder.spans = this.spanRecorder.spans.filter((span) => {
            // If we are dealing with the transaction itself, we just return it
            if (span.spanId === this.spanId) {
              return true;
            }
    
            // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early
            if (!span.endTimestamp) {
              span.endTimestamp = endTimestamp;
              span.setStatus('cancelled');
              (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
    
                _sentry_utils__WEBPACK_IMPORTED_MODULE_3__.logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2));
    
            }
    
            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');
    
          (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}`);
    
        (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
    
    
    /***/ }),
    
    /***/ ((__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__(1616);
    /* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1548);
    /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1611);
    
    /**
     * 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
    
    /***/ ((__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__(1544);
    /* harmony import */ var _logger_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1548);
    /* harmony import */ var _object_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1545);
    /* harmony import */ var _stacktrace_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1557);
    /* harmony import */ var _supports_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1617);
    /* harmony import */ var _worldwide_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1539);
    
    // 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 */
    
    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);
    
    /** 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
    
    /**
     * 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,