handleTransactionEnd()

in packages/rum-core/src/performance-monitoring/transaction-service.js [238:362]


  handleTransactionEnd(tr) {
    /**
     * Stop the observer once the transaction ends as we would like to
     * get notified only when transaction is happening instead of observing
     * all the time
     */
    this.recorder.stop()

    /**
     * Capturing it here before scheduling the transaction end
     * as to avoid capture different location when routed
     */
    const currentUrl = window.location.href

    return Promise.resolve().then(
      () => {
        const { name, type } = tr
        let { lastHiddenStart } = state
        if (lastHiddenStart >= tr._start) {
          if (__DEV__) {
            this._logger.debug(
              `transaction(${tr.id}, ${name}, ${type}) was discarded! The page was hidden during the transaction!`
            )
          }
          this._config.dispatchEvent(TRANSACTION_IGNORE)
          return
        }

        if (this.shouldIgnoreTransaction(name) || type === TEMPORARY_TYPE) {
          if (__DEV__) {
            this._logger.debug(
              `transaction(${tr.id}, ${name}, ${type}) is ignored`
            )
          }
          this._config.dispatchEvent(TRANSACTION_IGNORE)
          return
        }

        if (type === PAGE_LOAD) {
          /**
           * Setting the pageLoadTransactionName via configService.setConfig after
           * transaction has started should also reflect the correct name.
           */
          const pageLoadTransactionName = this._config.get(
            'pageLoadTransactionName'
          )
          if (name === NAME_UNKNOWN && pageLoadTransactionName) {
            tr.name = pageLoadTransactionName
          }
          
          /**
           * Capture the TBT as span after observing for all long task entries
           * and once performance observer is disconnected
           */
          if (tr.captureTimings) {
            const { cls, fid, tbt, longtask } = metrics
            if (tbt.duration > 0) {
              tr.spans.push(createTotalBlockingTimeSpan(tbt))
            }

            tr.experience = {}
            if (isPerfTypeSupported(LONG_TASK)) {
              tr.experience.tbt = tbt.duration
            }

            if (isPerfTypeSupported(LAYOUT_SHIFT)) {
              tr.experience.cls = cls.score
            }

            if (fid > 0) {
              tr.experience.fid = fid
            }

            if (longtask.count > 0) {
              tr.experience.longtask = {
                count: longtask.count,
                sum: longtask.duration,
                max: longtask.max
              }
            }
          }
          this.setSession(tr)
        }
        /**
         * Categorize the transaction based on the current location
         */
        if (tr.name === NAME_UNKNOWN) {
          tr.name = slugifyUrl(currentUrl)
        }

        captureNavigation(tr)

        /**
         * Adjust transaction start time with span timings and
         * truncate spans that goes beyond transaction timeframe
         */
        this.adjustTransactionTime(tr)
        /**
         * Capture breakdown metrics once the transaction is completed
         */
        const breakdownMetrics = this._config.get('breakdownMetrics')
        if (breakdownMetrics) {
          tr.captureBreakdown()
        }
        const configContext = this._config.get('context')
        addTransactionContext(tr, configContext)

        this._config.events.send(TRANSACTION_END, [tr])
        if (__DEV__) {
          this._logger.debug(
            `end transaction(${tr.id}, ${tr.name}, ${tr.type})`,
            tr
          )
        }
      },
      err => {
        if (__DEV__) {
          this._logger.debug(
            `error ending transaction(${tr.id}, ${tr.name})`,
            err
          )
        }
      }
    )
  }