File tree Expand file tree Collapse file tree 12 files changed +263
-13
lines changed
browser-integration-tests/suites/public-api/startSpan
error-async-throw-not-awaited Expand file tree Collapse file tree 12 files changed +263
-13
lines changed Original file line number Diff line number Diff line change
1
+ async function run ( ) {
2
+ Sentry . startSpan ( { name : 'parent_span' } , ( ) => {
3
+ Sentry . startSpan ( { name : 'child_span' } , ( ) => {
4
+ // whatever a user would do here
5
+ } ) ;
6
+ } ) ;
7
+ }
8
+
9
+ run ( ) ;
Original file line number Diff line number Diff line change
1
+ import { expect } from '@playwright/test' ;
2
+ import type { Event } from '@sentry/types' ;
3
+
4
+ import { sentryTest } from '../../../../utils/fixtures' ;
5
+ import { getFirstSentryEnvelopeRequest , shouldSkipTracingTest } from '../../../../utils/helpers' ;
6
+
7
+ sentryTest ( 'should send a transaction in an envelope' , async ( { getLocalTestPath, page } ) => {
8
+ if ( shouldSkipTracingTest ( ) ) {
9
+ sentryTest . skip ( ) ;
10
+ }
11
+
12
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
13
+ const transaction = await getFirstSentryEnvelopeRequest < Event > ( page , url ) ;
14
+
15
+ expect ( transaction . transaction ) . toBe ( 'parent_span' ) ;
16
+ expect ( transaction . spans ) . toBeDefined ( ) ;
17
+ } ) ;
18
+
19
+ sentryTest ( 'should report finished spans as children of the root transaction' , async ( { getLocalTestPath, page } ) => {
20
+ if ( shouldSkipTracingTest ( ) ) {
21
+ sentryTest . skip ( ) ;
22
+ }
23
+
24
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
25
+ const transaction = await getFirstSentryEnvelopeRequest < Event > ( page , url ) ;
26
+
27
+ const rootSpanId = transaction ?. contexts ?. trace ?. spanId ;
28
+
29
+ expect ( transaction . spans ) . toHaveLength ( 1 ) ;
30
+
31
+ const span_1 = transaction . spans ?. [ 0 ] ;
32
+ expect ( span_1 ?. description ) . toBe ( 'child_span' ) ;
33
+ expect ( span_1 ?. parentSpanId ) . toEqual ( rootSpanId ) ;
34
+ } ) ;
Original file line number Diff line number Diff line change
1
+ <!DOCTYPE html>
2
+ < html >
3
+ < head >
4
+ < meta charset ="utf-8 " />
5
+ < title > </ title >
6
+ </ head >
7
+ < body >
8
+ < button id ="button1 " type ="button "> Button 1</ button >
9
+
10
+ < script >
11
+ async function run ( ) {
12
+ await Sentry . startSpan ( { name : 'parent_span' , op : 'test' } , async ( ) => {
13
+ Promise . reject ( 'Async Promise Rejection' ) ;
14
+ } ) ;
15
+ }
16
+
17
+ const button = document . getElementById ( 'button1' ) ;
18
+ button . addEventListener ( 'click' , async ( ) => {
19
+ await run ( ) ;
20
+ } ) ;
21
+ </ script >
22
+ </ body >
23
+ </ html >
Original file line number Diff line number Diff line change
1
+ import { expect } from '@playwright/test' ;
2
+ import type { Event } from '@sentry/types' ;
3
+
4
+ import { sentryTest } from '../../../../utils/fixtures' ;
5
+ import { getMultipleSentryEnvelopeRequests , shouldSkipTracingTest } from '../../../../utils/helpers' ;
6
+
7
+ sentryTest (
8
+ 'should capture a promise rejection within an async startSpan callback' ,
9
+ async ( { getLocalTestPath, page } ) => {
10
+ if ( shouldSkipTracingTest ( ) ) {
11
+ sentryTest . skip ( ) ;
12
+ }
13
+
14
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
15
+ const envelopePromise = getMultipleSentryEnvelopeRequests < Event > ( page , 2 ) ;
16
+
17
+ await page . goto ( url ) ;
18
+
19
+ const clickPromise = page . getByText ( 'Button 1' ) . click ( ) ;
20
+
21
+ const [ , events ] = await Promise . all ( [ clickPromise , envelopePromise ] ) ;
22
+ const txn = events . find ( event => event . type === 'transaction' ) ;
23
+ const err = events . find ( event => ! event . type ) ;
24
+
25
+ expect ( txn ) . toMatchObject ( { transaction : 'parent_span' } ) ;
26
+
27
+ expect ( err ?. exception ?. values ?. [ 0 ] ?. value ) . toBe (
28
+ 'Non-Error promise rejection captured with value: Async Promise Rejection' ,
29
+ ) ;
30
+ } ,
31
+ ) ;
Original file line number Diff line number Diff line change
1
+ <!DOCTYPE html>
2
+ < html >
3
+ < head >
4
+ < meta charset ="utf-8 " />
5
+ < title > </ title >
6
+ </ head >
7
+ < body >
8
+ < button id ="button1 " type ="button "> Button 1</ button >
9
+
10
+ < script type ="module ">
11
+ async function run ( ) {
12
+ Sentry . startSpan ( { name : 'parent_span' , op : 'test' } , async ( ) => {
13
+ throw new Error ( 'Async Thrown Error' ) ;
14
+ } ) ;
15
+ }
16
+
17
+ const button = document . getElementById ( 'button1' ) ;
18
+ button . addEventListener ( 'click' , ( ) => {
19
+ void run ( ) ;
20
+ } ) ;
21
+ </ script >
22
+ </ body >
23
+ </ html >
Original file line number Diff line number Diff line change
1
+ import { expect } from '@playwright/test' ;
2
+ import type { Event } from '@sentry/types' ;
3
+
4
+ import { sentryTest } from '../../../../utils/fixtures' ;
5
+ import { getMultipleSentryEnvelopeRequests , shouldSkipTracingTest } from '../../../../utils/helpers' ;
6
+
7
+ sentryTest (
8
+ "should capture a thrown error within an async startSpan callback that's not awaited properly" ,
9
+ async ( { getLocalTestPath, page } ) => {
10
+ if ( shouldSkipTracingTest ( ) ) {
11
+ sentryTest . skip ( ) ;
12
+ }
13
+ const envelopePromise = getMultipleSentryEnvelopeRequests < Event > ( page , 2 ) ;
14
+
15
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
16
+ await page . goto ( url ) ;
17
+
18
+ const clickPromise = page . getByText ( 'Button 1' ) . click ( ) ;
19
+
20
+ // awaiting both events simultaneously to avoid race conditions
21
+ const [ , events ] = await Promise . all ( [ clickPromise , envelopePromise ] ) ;
22
+ const txn = events . find ( event => event . type === 'transaction' ) ;
23
+ const err = events . find ( event => ! event . type ) ;
24
+
25
+ expect ( txn ) . toMatchObject ( { transaction : 'parent_span' } ) ;
26
+ expect ( err ?. exception ?. values ?. [ 0 ] ?. value ) . toBe ( 'Async Thrown Error' ) ;
27
+ } ,
28
+ ) ;
Original file line number Diff line number Diff line change
1
+ <!DOCTYPE html>
2
+ < html >
3
+ < head >
4
+ < meta charset ="utf-8 " />
5
+ < title > </ title >
6
+ </ head >
7
+ < body >
8
+ < button id ="button1 " type ="button "> Button 1</ button >
9
+
10
+ < script type ="module ">
11
+ async function run ( ) {
12
+ await Promise . resolve ( ) ;
13
+ await Sentry . startSpan ( { name : 'parent_span' , op : 'test' } , async ( ) => {
14
+ throw new Error ( 'Async Thrown Error' ) ;
15
+ } ) ;
16
+ }
17
+
18
+ const button = document . getElementById ( 'button1' ) ;
19
+ button . addEventListener ( 'click' , ( ) => {
20
+ void run ( ) ;
21
+ } ) ;
22
+ </ script >
23
+ </ body >
24
+ </ html >
Original file line number Diff line number Diff line change
1
+ import { expect } from '@playwright/test' ;
2
+ import type { Event } from '@sentry/types' ;
3
+
4
+ import { sentryTest } from '../../../../utils/fixtures' ;
5
+ import { getMultipleSentryEnvelopeRequests , shouldSkipTracingTest } from '../../../../utils/helpers' ;
6
+
7
+ sentryTest ( 'should capture a thrown error within an async startSpan callback' , async ( { getLocalTestPath, page } ) => {
8
+ if ( shouldSkipTracingTest ( ) ) {
9
+ sentryTest . skip ( ) ;
10
+ }
11
+ const envelopePromise = getMultipleSentryEnvelopeRequests < Event > ( page , 2 ) ;
12
+
13
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
14
+ await page . goto ( url ) ;
15
+
16
+ const clickPromise = page . getByText ( 'Button 1' ) . click ( ) ;
17
+
18
+ // awaiting both events simultaneously to avoid race conditions
19
+ const [ , events ] = await Promise . all ( [ clickPromise , envelopePromise ] ) ;
20
+ const txn = events . find ( event => event . type === 'transaction' ) ;
21
+ const err = events . find ( event => ! event . type ) ;
22
+
23
+ expect ( txn ) . toMatchObject ( { transaction : 'parent_span' } ) ;
24
+ expect ( err ?. exception ?. values ?. [ 0 ] ?. value ) . toBe ( 'Async Thrown Error' ) ;
25
+ } ) ;
Original file line number Diff line number Diff line change
1
+ function run ( ) {
2
+ Sentry . startSpan ( { name : 'parent_span' } , ( ) => {
3
+ throw new Error ( 'Sync Error' ) ;
4
+ } ) ;
5
+ }
6
+
7
+ // using `setTimeout` here because otherwise the thrown error will be
8
+ // thrown as a generic "Script Error." instead of the actual error".
9
+ setTimeout ( run ) ;
Original file line number Diff line number Diff line change
1
+ import { expect } from '@playwright/test' ;
2
+ import type { Event } from '@sentry/types' ;
3
+
4
+ import { sentryTest } from '../../../../utils/fixtures' ;
5
+ import { getMultipleSentryEnvelopeRequests , shouldSkipTracingTest } from '../../../../utils/helpers' ;
6
+
7
+ sentryTest ( 'should capture an error within a sync startSpan callback' , async ( { getLocalTestPath, page } ) => {
8
+ if ( shouldSkipTracingTest ( ) ) {
9
+ sentryTest . skip ( ) ;
10
+ }
11
+
12
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
13
+ const gotoPromise = page . goto ( url ) ;
14
+ const envelopePromise = getMultipleSentryEnvelopeRequests < Event > ( page , 2 ) ;
15
+
16
+ const [ _ , events ] = await Promise . all ( [ gotoPromise , envelopePromise ] ) ;
17
+ const txn = events . find ( event => event . type === 'transaction' ) ;
18
+ const err = events . find ( event => ! event . type ) ;
19
+
20
+ expect ( txn ) . toMatchObject ( { transaction : 'parent_span' } ) ;
21
+ expect ( err ?. exception ?. values ?. [ 0 ] ?. value ) . toBe ( 'Sync Error' ) ;
22
+ } ) ;
You can’t perform that action at this time.
0 commit comments