8000 fix(tracing-internal): Only collect request/response spans when brows… · getsentry/sentry-javascript@03a3d93 · GitHub
[go: up one dir, main page]

Skip to content

Commit 03a3d93

Browse files
authored
fix(tracing-internal): Only collect request/response spans when browser performance timing is available (#10207)
1 parent e50cc8a commit 03a3d93

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const dynamic = 'force-dynamic';
2+
3+
export default async function SuperSlowPage() {
4+
await new Promise(resolve => setTimeout(resolve, 10000));
5+
return null;
6+
}

dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/transactions.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,20 @@ test('Should send a transaction for instrumented server actions', async ({ page
139139

140140
expect(Object.keys((await serverComponentTransactionPromise).request?.headers || {}).length).toBeGreaterThan(0);
141141
});
142+
143+
test('Will not include spans in pageload transaction with faulty timestamps for slow loading pages', async ({
144+
page,
145+
}) => {
146+
const pageloadTransactionEventPromise = waitForTransaction('nextjs-13-app-dir', transactionEvent => {
147+
return (
148+
transactionEvent?.contexts?.trace?.op === 'pageload' && transactionEvent?.transaction === '/very-slow-component'
149+
);
150+
});
151+
152+
await page.goto('/very-slow-component');
153+
154+
const pageLoadTransaction = await pageloadTransactionEventPromise;
155+
156+
// @ts-expect-error We are looking at the serialized span format here
157+
expect(pageLoadTransaction.spans?.filter(span => span.timestamp < span.start_timestamp)).toHaveLength(0);
158+
});

packages/tracing-internal/src/browser/metrics/index.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -372,21 +372,27 @@ function _addPerformanceNavigationTiming(
372372
/** Create request and response related spans */
373373
// eslint-disable-next-line @typescript-eslint/no-explicit-any
374374
function _addRequest(transaction: Transaction, entry: Record<string, any>, timeOrigin: number): void {
375-
_startChild(transaction, {
376-
op: 'browser',
377-
origin: 'auto.browser.browser.metrics',
378-
description: 'request',
379-
startTimestamp: timeOrigin + msToSec(entry.requestStart as number),
380-
endTimestamp: timeOrigin + msToSec(entry.responseEnd as number),
381-
});
375+
if (entry.responseEnd) {
376+
// It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.
377+
// In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.
378+
// In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect
379+
// these spans when the responseEnd value is available. The backend (Relay) would drop the entire transaction if it contained faulty spans.
380+
_startChild(transaction, {
381+
op: 'browser',
382+
origin: 'auto.browser.browser.metrics',
383+
description: 'request',
384+
startTimestamp: timeOrigin + msToSec(entry.requestStart as number),
385+
endTimestamp: timeOrigin + msToSec(entry.responseEnd as number),
386+
});
382387

383-
_startChild(transaction, {
384-
op: 'browser',
385-
origin: 'auto.browser.browser.metrics',
386-
description: 'response',
387-
startTimestamp: timeOrigin + msToSec(entry.responseStart as number),
388-
endTimestamp: timeOrigin + msToSec(entry.responseEnd as number),
389-
});
388+
_startChild(transaction, {
389+
op: 'browser',
390+
origin: 'auto.browser.browser.metrics',
391+
description: 'response',
392+
startTimestamp: timeOrigin + msToSec(entry.responseStart as number),
393+
endTimestamp: timeOrigin + msToSec(entry.responseEnd as number),
394+
});
395+
}
390396
}
391397

392398
export interface ResourceEntry extends Record<string, unknown> {

0 commit comments

Comments
 (0)
0