Skip to content

Commit 98854d4

Browse files
authored
fix(core): continueTrace doesn't propagate given trace ID if active span exists (#18328)
During investigation of [this issue](#18296), we discovered that `continueTrace` does not propagate the given trace ID if it is called from within an already active span (in this instance this happened because of the already active span started by the cloudflare auto-instrumentation. Solution: This PR resolves this behavior by setting the currently active span to undefined when forking the propagation context in `continueTrace`. Tests: - After introducing the fix one of the `@sentry/sveltekit` unit tests started to fail. Not sure why this was triggered by this change, but I fixed it by setting the `isSubRequest` property on the event instead of the route, which seems correct to me. - Added a unit test in `@sentry/core` that calls `continueTrace` inside an active span and checks that the trace id is now propagated as we would expect.
1 parent f3bdfd7 commit 98854d4

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

packages/core/src/tracing/trace.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ export const continueTrace = <V>(
226226
return withScope(scope => {
227227
const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);
228228
scope.setPropagationContext(propagationContext);
229+
_setSpanForScope(scope, undefined);
229230
return callback();
230231
});
231232
};

packages/core/test/lib/tracing/trace.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
getGlobalScope,
55
getIsolationScope,
66
getMainCarrier,
7+
getTraceData,
78
Scope,
89
SEMANTIC_ATTRIBUTE_SENTRY_OP,
910
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
@@ -2021,6 +2022,74 @@ describe('continueTrace', () => {
20212022
});
20222023
});
20232024
});
2025+
2026+
it('updates the propagation context when called inside an active span', () => {
2027+
const client = new TestClient(
2028+
getDefaultTestClientOptions({
2029+
dsn: 'https://username@domain/123',
2030+
tracesSampleRate: 1,
2031+
}),
2032+
);
2033+
setCurrentClient(client);
2034+
client.init();
2035+
2036+
const sentryTrace = '12312012123120121231201212312012-1121201211212012-1';
2037+
const sentryTraceId = '12312012123120121231201212312012';
2038+
const sentryBaggage = 'sentry-org_id=123';
2039+
2040+
startSpan({ name: 'outer' }, () => {
2041+
continueTrace(
2042+
{
2043+
sentryTrace: sentryTrace,
2044+
baggage: sentryBaggage,
2045+
},
2046+
() => {
2047+
const traceDataInContinuedTrace = getTraceData();
2048+
const traceIdInContinuedTrace = traceDataInContinuedTrace['sentry-trace']?.split('-')[0];
2049+
const traceIdInCurrentScope = getCurrentScope().getPropagationContext().traceId;
2050+
2051+
expect(getActiveSpan()).toBeUndefined();
2052+
expect(traceIdInContinuedTrace).toBe(sentryTraceId);
2053+
expect(traceIdInCurrentScope).toBe(sentryTraceId);
2054+
},
2055+
);
2056+
});
2057+
});
2058+
2059+
it('sets the correct trace and parent span ids when called inside an active span and a new span is started from within the callback', () => {
2060+
const client = new TestClient(
2061+
getDefaultTestClientOptions({
2062+
dsn: 'https://username@domain/123',
2063+
tracesSampleRate: 1,
2064+
}),
2065+
);
2066+
setCurrentClient(client);
2067+
client.init();
2068+
2069+
const sentryTrace = '12312012123120121231201212312012-1121201211212012-1';
2070+
const sentryTraceId = '12312012123120121231201212312012';
2071+
const sentrySpanId = '1121201211212012';
2072+
const sentryBaggage = 'sentry-org_id=123';
2073+
2074+
startSpan({ name: 'outer' }, () => {
2075+
continueTrace(
2076+
{
2077+
sentryTrace: sentryTrace,
2078+
baggage: sentryBaggage,
2079+
},
2080+
() => {
2081+
startSpan({ name: 'inner' }, span => {
2082+
const innerSpanJson = spanToJSON(span);
2083+
const innerTraceId = innerSpanJson.trace_id;
2084+
const innerParentSpanId = innerSpanJson.parent_span_id;
2085+
2086+
expect(innerTraceId).toBe(sentryTraceId);
2087+
expect(innerParentSpanId).toBe(sentrySpanId);
2088+
});
2089+
},
2090+
);
2091+
});
2092+
});
20242093
});
20252094

20262095
describe('getActiveSpan', () => {

packages/sveltekit/test/server-common/handle.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ describe('sentryHandle', () => {
186186
resolve: async _ => {
187187
// simulating a nested load call:
188188
await sentryHandle()({
189-
event: mockEvent({ route: { id: 'api/users/details/[id]', isSubRequest: true } }),
189+
event: mockEvent({ route: { id: 'api/users/details/[id]' }, isSubRequest: true }),
190190
resolve: resolve(type, isError),
191191
});
192192
return mockResponse;

0 commit comments

Comments
 (0)