diff --git a/packages/core/src/tracing/idletransaction.ts b/packages/core/src/tracing/idletransaction.ts index 4939a4fe58bd..afb81fd2dbf8 100644 --- a/packages/core/src/tracing/idletransaction.ts +++ b/packages/core/src/tracing/idletransaction.ts @@ -111,9 +111,6 @@ export class IdleTransaction extends Transaction { super(transactionContext, _idleHub); 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. __DEBUG_BUILD__ && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanId}`); @@ -179,7 +176,10 @@ export class IdleTransaction extends Transaction { // if `this._onScope` is `true`, the transaction put itself on the scope when it started if (this._onScope) { - clearActiveTransaction(this._idleHub); + const scope = this._idleHub.getScope(); + if (scope.getTransaction() === this) { + scope.setSpan(undefined); + } } return super.finish(endTimestamp); @@ -353,13 +353,3 @@ export class IdleTransaction extends Transaction { }, this._heartbeatInterval); } } - -/** - * Reset transaction on scope to `undefined` - */ -function clearActiveTransaction(hub: Hub): void { - const scope = hub.getScope(); - if (scope.getTransaction()) { - scope.setSpan(undefined); - } -} diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index a3382bacabbe..027559c02296 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -1,5 +1,5 @@ import { BrowserClient } from '@sentry/browser'; -import { TRACING_DEFAULTS } from '@sentry/core'; +import { TRACING_DEFAULTS, Transaction } from '@sentry/core'; import { Hub, IdleTransaction, Span } from '../../core/src'; import { IdleTransactionSpanRecorder } from '../../core/src/tracing/idletransaction'; @@ -75,6 +75,29 @@ describe('IdleTransaction', () => { expect(s.getTransaction()).toBe(undefined); }); }); + + it('does not remove transaction from scope on finish if another transaction was set there', () => { + const transaction = new IdleTransaction( + { name: 'foo' }, + hub, + TRACING_DEFAULTS.idleTimeout, + TRACING_DEFAULTS.finalTimeout, + TRACING_DEFAULTS.heartbeatInterval, + true, + ); + transaction.initSpanRecorder(10); + + // @ts-ignore need to pass in hub + const otherTransaction = new Transaction({ name: 'bar' }, hub); + hub.getScope().setSpan(otherTransaction); + + transaction.finish(); + jest.runAllTimers(); + + hub.configureScope(s => { + expect(s.getTransaction()).toBe(otherTransaction); + }); + }); }); beforeEach(() => {