Skip to content

Commit f833ab2

Browse files
authored
fix(tracing): Set correct parent span id on fetch sentry-trace header (#8687)
In slack we reported a bug where there seemed to be the wrong parent span id attached to outgoing `sentry-trace` headers. This ends up being because the `addTracingHeadersToFetchRequest` attempts to use the transaction instead of the active request span to generate the outgoing `sentry-trace` header. This fixes that by adding the span to the `addTracingHeadersToFetchRequest` method.
1 parent a5fdaee commit f833ab2

File tree

3 files changed

+34
-23
lines changed

3 files changed

+34
-23
lines changed

packages/sveltekit/src/client/load.ts

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { BaseClient } from '@sentry/core';
33
import { getCurrentHub, trace } from '@sentry/core';
44
import type { Breadcrumbs, BrowserTracing } from '@sentry/svelte';
55
import { captureException } from '@sentry/svelte';
6-
import type { Client, ClientOptions, SanitizedRequestData } from '@sentry/types';
6+
import type { Client, ClientOptions, SanitizedRequestData, Span } from '@sentry/types';
77
import {
88
addExceptionMechanism,
99
addNonEnumerableProperty,
@@ -186,26 +186,16 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
186186
const scope = hub.getScope();
187187
const client = hub.getClient();
188188

189-
if (client && shouldAttachHeaders(rawUrl)) {
190-
const headers = addTracingHeadersToFetchRequest(
191-
input as string | Request,
192-
client,
193-
scope,
194-
patchedInit as {
195-
headers:
196-
| {
197-
[key: string]: string[] | string | undefined;
198-
}
199-
| Request['headers'];
200-
},
201-
) as HeadersInit;
202-
203-
patchedInit.headers = headers;
204-
}
205-
206189
let fetchPromise: Promise<Response>;
207190

208-
const patchedFetchArgs = [input, patchedInit];
191+
function callFetchTarget(span?: Span): Promise<Response> {
192+
if (client && shouldAttachHeaders(rawUrl)) {
193+
const headers = addTracingHeadersToFetchRequest(input as string | Request, client, scope, patchedInit, span);
194+
patchedInit.headers = headers as HeadersInit;
195+
}
196+
const patchedFetchArgs = [input, patchedInit];
197+
return wrappingTarget.apply(thisArg, patchedFetchArgs);
198+
}
209199

210200
if (shouldCreateSpan(rawUrl)) {
211201
fetchPromise = trace(
@@ -215,15 +205,15 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
215205
data: requestData,
216206
},
217207
span => {
218-
const promise: Promise<Response> = wrappingTarget.apply(thisArg, patchedFetchArgs);
208+
const promise = callFetchTarget(span);
219209
if (span) {
220210
promise.then(res => span.setHttpStatus(res.status)).catch(_ => span.setStatus('internal_error'));
221211
}
222212
return promise;
223213
},
224214
);
225215
} else {
226-
fetchPromise = wrappingTarget.apply(thisArg, patchedFetchArgs);
216+
fetchPromise = callFetchTarget();
227217
}
228218

229219
if (shouldAddFetchBreadcrumb) {

packages/tracing-internal/src/browser/request.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export function fetchCallback(
340340
const options: { [key: string]: any } = handlerData.args[1];
341341

342342
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
343-
options.headers = addTracingHeadersToFetchRequest(request, client, scope, options);
343+
options.headers = addTracingHeadersToFetchRequest(request, client, scope, options, span);
344344
}
345345

346346
return span;
@@ -360,8 +360,9 @@ export function addTracingHeadersToFetchRequest(
360360
}
361361
| PolymorphicRequestHeaders;
362362
},
363+
requestSpan?: Span,
363364
): PolymorphicRequestHeaders | undefined {
364-
const span = scope.getSpan();
365+
const span = requestSpan || scope.getSpan();
365366

366367
const transaction = span && span.transaction;
367368

packages/tracing-internal/test/browser/request.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,26 @@ describe('callbacks', () => {
218218
expect(newSpan).toBeUndefined();
219219
});
220220

221+
it('uses active span to generate sentry-trace header', () => {
222+
const spans: Record<string, Span> = {};
223+
// triggered by request being sent
224+
fetchCallback(fetchHandlerData, alwaysCreateSpan, alwaysAttachHeaders, spans);
225+
226+
const activeSpan = transaction.spanRecorder?.spans[1] as Span;
227+
228+
const postRequestFetchHandlerData = {
229+
...fetchHandlerData,
230+
endTimestamp,
231+
response: { status: 200 } as Response,
232+
};
233+
234+
// triggered by response coming back
235+
fetchCallback(postRequestFetchHandlerData, alwaysCreateSpan, alwaysAttachHeaders, spans);
236+
237+
const headers = (fetchHandlerData.args[1].headers as Record<string, string>) || {};
238+
expect(headers['sentry-trace']).toEqual(`${activeSpan.traceId}-${activeSpan.spanId}-1`);
239+
});
240+
221241
it('adds content-length to span data on finish', () => {
222242
const spans: Record<string, Span> = {};
223243

0 commit comments

Comments
 (0)