Skip to content

Commit be2f037

Browse files
committed
fix: set headers before they get frozen
1 parent 8777dbf commit be2f037

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

packages/nitro/src/runtime/hooks/captureTracingEvents.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import type { TracingRequestEvent as H3TracingRequestEvent } from 'h3/tracing';
2020
import { tracingChannel } from 'otel-tracing-channel';
2121
import type { RequestEvent as SrvxRequestEvent } from 'srvx/tracing';
22+
import { setServerTimingHeaders } from './setServerTimingHeaders';
2223

2324
/**
2425
* Global object with the trace channels
@@ -118,7 +119,9 @@ function setupH3TracingChannels(): void {
118119
});
119120

120121
h3Channel.subscribe({
121-
start: NOOP,
122+
start: (data: H3TracingRequestEvent) => {
123+
setServerTimingHeaders(data.event);
124+
},
122125
asyncStart: NOOP,
123126
end: NOOP,
124127
asyncEnd: (data: H3TracingRequestEvent & { span?: Span; result?: unknown }) => {
Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
import { getTraceData } from '@sentry/core';
2+
import type { TracingRequestEvent as H3TracingRequestEvent } from 'h3/tracing';
23

34
/**
45
* Sets Server-Timing response headers for trace propagation to the client.
56
* The browser SDK reads these via the Performance API to connect pageload traces.
67
*/
7-
export function setServerTimingHeaders(response: unknown, _event: unknown): void {
8-
if (response && typeof response === 'object' && 'headers' in response) {
9-
const responseObj = response as Response;
10-
const traceData = getTraceData();
8+
export function setServerTimingHeaders(event: H3TracingRequestEvent['event']): void {
9+
if (event.context._sentryServerTimingSet) {
10+
return;
11+
}
12+
13+
const headers = event.res?.headers;
14+
if (!headers) {
15+
return;
16+
}
1117

12-
if (traceData['sentry-trace']) {
13-
responseObj.headers.append('Server-Timing', `sentry-trace;desc="${traceData['sentry-trace']}"`);
14-
}
15-
if (traceData.baggage) {
16-
responseObj.headers.append('Server-Timing', `baggage;desc="${traceData.baggage}"`);
17-
}
18+
const traceData = getTraceData();
19+
if (traceData['sentry-trace']) {
20+
headers.append('Server-Timing', `sentry-trace;desc="${traceData['sentry-trace']}"`);
1821
}
22+
if (traceData.baggage) {
23+
headers.append('Server-Timing', `baggage;desc="${traceData.baggage}"`);
24+
}
25+
26+
event.context._sentryServerTimingSet = true;
1927
}
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import { definePlugin } from 'nitro';
22
import { captureErrorHook } from '../hooks/captureErrorHook';
33
import { captureTracingEvents } from '../hooks/captureTracingEvents';
4-
import { setServerTimingHeaders } from '../hooks/setServerTimingHeaders';
54

65
export default definePlugin(nitroApp => {
76
// FIXME: Nitro hooks are not typed it seems
87
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
98
nitroApp.hooks.hook('error', captureErrorHook);
109

11-
// FIXME: Nitro hooks are not typed it seems
12-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
13-
nitroApp.hooks.hook('response', setServerTimingHeaders);
14-
1510
captureTracingEvents();
1611
});

0 commit comments

Comments
 (0)