Skip to content
25 changes: 21 additions & 4 deletions packages/core/src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { Client, HandlerDataFetch, Scope, Span, SpanOrigin } from '@sentry/types';
import {
BAGGAGE_HEADER_NAME,
SENTRY_BAGGAGE_KEY_PREFIX,
SENTRY_BAGGAGE_KEY_PREFIX_REGEX,
dynamicSamplingContextToSentryBaggageHeader,
generateSentryTraceHeader,
isInstanceOf,
parseBaggageHeader,
parseUrl,
} from '@sentry/utils';
import { getClient, getCurrentScope, getIsolationScope } from './currentScopes';
Expand Down Expand Up @@ -153,12 +156,26 @@ export function addTracingHeadersToFetchRequest(
} else if (typeof Headers !== 'undefined' && isInstanceOf(headers, Headers)) {
const newHeaders = new Headers(headers as Headers);

newHeaders.append('sentry-trace', sentryTraceHeader);
newHeaders.set('sentry-trace', sentryTraceHeader);

if (sentryBaggageHeader) {
// If the same header is appended multiple times the browser will merge the values into a single request header.
// Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header.
newHeaders.append(BAGGAGE_HEADER_NAME, sentryBaggageHeader);
const prevBaggageHeader = newHeaders.get(BAGGAGE_HEADER_NAME);
if (prevBaggageHeader) {
const prevHeaderStrippedFromSentryBaggage = sentryBaggageHeader
.split(',')
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.filter(baggageEntry => !baggageEntry.split('=')[0]!.startsWith(SENTRY_BAGGAGE_KEY_PREFIX))
.join(',');

const mergedHeaders = [sentryBaggageHeader];
if (prevHeaderStrippedFromSentryBaggage) {
mergedHeaders.unshift(prevHeaderStrippedFromSentryBaggage);
}

newHeaders.set(BAGGAGE_HEADER_NAME, mergedHeaders.join(','));
} else {
newHeaders.set(BAGGAGE_HEADER_NAME, sentryBaggageHeader);
}
}

return newHeaders as PolymorphicRequestHeaders;
Expand Down
Loading