-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Fork scope and keep async context within
startSpan
and `startS…
…panManual` (#10413)
- Loading branch information
Showing
2 changed files
with
202 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { setAsyncContextStrategy, setCurrentClient, startSpan, startSpanManual } from '@sentry/core'; | ||
import type { TransactionEvent } from '@sentry/types'; | ||
import { NodeClient, defaultStackParser } from '../src'; | ||
import { setNodeAsyncContextStrategy } from '../src/async'; | ||
import { getDefaultNodeClientOptions } from './helper/node-client-options'; | ||
|
||
const dsn = 'https://[email protected]/4291'; | ||
|
||
beforeAll(() => { | ||
setNodeAsyncContextStrategy(); | ||
}); | ||
|
||
afterAll(() => { | ||
setAsyncContextStrategy(undefined); | ||
}); | ||
|
||
describe('startSpan()', () => { | ||
it('should correctly separate spans when called after one another with interwoven timings', async () => { | ||
const transactionEventPromise = new Promise<TransactionEvent>(resolve => { | ||
setCurrentClient( | ||
new NodeClient( | ||
getDefaultNodeClientOptions({ | ||
stackParser: defaultStackParser, | ||
tracesSampleRate: 1, | ||
beforeSendTransaction: event => { | ||
resolve(event); | ||
return null; | ||
}, | ||
dsn, | ||
}), | ||
), | ||
); | ||
}); | ||
|
||
startSpan({ name: 'first' }, () => { | ||
return new Promise<void>(resolve => { | ||
setTimeout(resolve, 500); | ||
}); | ||
}); | ||
|
||
startSpan({ name: 'second' }, () => { | ||
return new Promise<void>(resolve => { | ||
setTimeout(resolve, 250); | ||
}); | ||
}); | ||
|
||
const transactionEvent = await transactionEventPromise; | ||
|
||
// Any transaction events happening shouldn't have any child spans | ||
expect(transactionEvent.spans).toStrictEqual([]); | ||
}); | ||
|
||
it('should correctly nest spans when called within one another', async () => { | ||
const transactionEventPromise = new Promise<TransactionEvent>(resolve => { | ||
setCurrentClient( | ||
new NodeClient( | ||
getDefaultNodeClientOptions({ | ||
stackParser: defaultStackParser, | ||
tracesSampleRate: 1, | ||
beforeSendTransaction: event => { | ||
resolve(event); | ||
return null; | ||
}, | ||
dsn, | ||
}), | ||
), | ||
); | ||
}); | ||
|
||
startSpan({ name: 'first' }, () => { | ||
startSpan({ name: 'second' }, () => undefined); | ||
}); | ||
|
||
const transactionEvent = await transactionEventPromise; | ||
|
||
expect(transactionEvent.spans).toContainEqual(expect.objectContaining({ description: 'second' })); | ||
}); | ||
}); | ||
|
||
describe('startSpanManual()', () => { | ||
it('should correctly separate spans when called after one another with interwoven timings', async () => { | ||
const transactionEventPromise = new Promise<TransactionEvent>(resolve => { | ||
setCurrentClient( | ||
new NodeClient( | ||
getDefaultNodeClientOptions({ | ||
stackParser: defaultStackParser, | ||
tracesSampleRate: 1, | ||
beforeSendTransaction: event => { | ||
resolve(event); | ||
return null; | ||
}, | ||
dsn, | ||
}), | ||
), | ||
); | ||
}); | ||
|
||
startSpanManual({ name: 'first' }, span => { | ||
return new Promise<void>(resolve => { | ||
setTimeout(() => { | ||
span?.end(); | ||
resolve(); | ||
}, 500); | ||
}); | ||
}); | ||
|
||
startSpanManual({ name: 'second' }, span => { | ||
return new Promise<void>(resolve => { | ||
setTimeout(() => { | ||
span?.end(); | ||
resolve(); | ||
}, 500); | ||
}); | ||
}); | ||
|
||
const transactionEvent = await transactionEventPromise; | ||
|
||
// Any transaction events happening shouldn't have any child spans | ||
expect(transactionEvent.spans).toStrictEqual([]); | ||
}); | ||
|
||
it('should correctly nest spans when called within one another', async () => { | ||
const transactionEventPromise = new Promise<TransactionEvent>(resolve => { | ||
setCurrentClient( | ||
new NodeClient( | ||
getDefaultNodeClientOptions({ | ||
stackParser: defaultStackParser, | ||
tracesSampleRate: 1, | ||
beforeSendTransaction: event => { | ||
resolve(event); | ||
return null; | ||
}, | ||
dsn, | ||
}), | ||
), | ||
); | ||
}); | ||
|
||
startSpanManual({ name: 'first' }, span1 => { | ||
startSpanManual({ name: 'second' }, span2 => { | ||
span2?.end(); | ||
}); | ||
span1?.end(); | ||
}); | ||
|
||
const transactionEvent = await transactionEventPromise; | ||
|
||
expect(transactionEvent.spans).toContainEqual(expect.objectContaining({ description: 'second' })); | ||
}); | ||
}); |