Skip to content

Commit 03d37ba

Browse files
authored
fix(tracing): Remove undefined tracestate data rather than setting it to null (#3373)
1 parent 271f7ec commit 03d37ba

File tree

3 files changed

+13
-17
lines changed

3 files changed

+13
-17
lines changed

packages/tracing/src/span.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ export class Span implements SpanInterface {
378378

379379
const { environment, release } = client.getOptions() || {};
380380

381+
// only define a `user` object if there's going to be something in it
382+
const user = userId || userSegment ? { id: userId, segment: userSegment } : undefined;
383+
381384
// TODO - the only reason we need the non-null assertion on `dsn.publicKey` (below) is because `dsn.publicKey` has
382385
// to be optional while we transition from `dsn.user` -> `dsn.publicKey`. Once `dsn.user` is removed, we can make
383386
// `dsn.publicKey` required and remove the `!`.
@@ -388,7 +391,7 @@ export class Span implements SpanInterface {
388391
release,
389392
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
390393
public_key: dsn.publicKey!,
391-
user: { id: userId, segment: userSegment },
394+
user,
392395
})}`;
393396
}
394397

packages/tracing/src/utils.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getCurrentHub, Hub } from '@sentry/hub';
22
import { Options, TraceparentData, Transaction } from '@sentry/types';
3-
import { SentryError, unicodeToBase64 } from '@sentry/utils';
3+
import { dropUndefinedKeys, SentryError, unicodeToBase64 } from '@sentry/utils';
44

55
export const SENTRY_TRACE_REGEX = new RegExp(
66
'^[ \\t]*' + // whitespace
@@ -146,10 +146,10 @@ export { stripUrlQueryAndFragment } from '@sentry/utils';
146146

147147
type SentryTracestateData = {
148148
trace_id: string;
149-
environment: string | undefined | null;
150-
release: string | undefined | null;
149+
environment?: string;
150+
release?: string;
151151
public_key: string;
152-
user: { id: string | undefined | null; segment: string | undefined | null };
152+
user?: { id?: string; segment?: string };
153153
};
154154

155155
/**
@@ -161,10 +161,6 @@ type SentryTracestateData = {
161161
export function computeTracestateValue(data: SentryTracestateData): string {
162162
// `JSON.stringify` will drop keys with undefined values, but not ones with null values, so this prevents
163163
// these values from being dropped if they haven't been set by `Sentry.init`
164-
data.environment = data.environment || null;
165-
data.release = data.release || null;
166-
data.user.id = data.user.id || null;
167-
data.user.segment = data.user.segment || null;
168164

169165
// See https://www.w3.org/TR/trace-context/#tracestate-header-field-values
170166
// The spec for tracestate header values calls for a string of the form
@@ -175,7 +171,7 @@ export function computeTracestateValue(data: SentryTracestateData): string {
175171
// used to pad the end of base64 values though, so to avoid confusion, we strip them off. (Most languages' base64
176172
// decoding functions (including those in JS) are able to function without the padding.)
177173
try {
178-
return unicodeToBase64(JSON.stringify(data)).replace(/={1,2}$/, '');
174+
return unicodeToBase64(JSON.stringify(dropUndefinedKeys(data))).replace(/={1,2}$/, '');
179175
} catch (err) {
180176
throw new SentryError(`[Tracing] Error computing tracestate value from data: ${err}\nData: ${data}`);
181177
}

packages/tracing/test/httpheaders.test.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,13 @@ describe('tracestate', () => {
166166

167167
describe('mutibility', () => {
168168
it("won't include data set after transaction is created if there's an inherited value", () => {
169-
expect.assertions(2);
169+
expect.assertions(1);
170170

171171
const inheritedTracestate = `sentry=${computeTracestateValue({
172172
trace_id: '12312012090820131231201209082013',
173173
environment: 'dogpark',
174174
release: 'off.leash.trail',
175175
public_key: 'dogsarebadatkeepingsecrets',
176-
user: { id: undefined, segment: undefined },
177176
})}`;
178177

179178
const transaction = new Transaction(
@@ -194,8 +193,7 @@ describe('tracestate', () => {
194193
const tracestateValue = (transaction as any)._toTracestate().replace('sentry=', '');
195194
const reinflatedTracestate = JSON.parse(base64ToUnicode(tracestateValue));
196195

197-
expect(reinflatedTracestate.user.id).toBeNull();
198-
expect(reinflatedTracestate.user.segment).toBeNull();
196+
expect(reinflatedTracestate.user).toBeUndefined();
199197
});
200198
});
201199

@@ -221,7 +219,7 @@ describe('tracestate', () => {
221219
});
222220

223221
it("won't include data set after first call to `getTraceHeaders`", () => {
224-
expect.assertions(2);
222+
expect.assertions(1);
225223

226224
const transaction = new Transaction(
227225
{
@@ -238,8 +236,7 @@ describe('tracestate', () => {
238236
const tracestateValue = (transaction as any)._toTracestate().replace('sentry=', '');
239237
const reinflatedTracestate = JSON.parse(base64ToUnicode(tracestateValue));
240238

241-
expect(reinflatedTracestate.user.id).toBeNull();
242-
expect(reinflatedTracestate.user.segment).toBeNull();
239+
expect(reinflatedTracestate.user).toBeUndefined();
243240
});
244241
});
245242
});

0 commit comments

Comments
 (0)