Skip to content

Commit c03883a

Browse files
committed
fix: Normalize Transaction and Span consistently
This is such that setting data on a Transaction behaves the same as setting data on a Span.
1 parent fc53353 commit c03883a

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

packages/core/src/baseclient.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
300300
}
301301

302302
// tslint:disable:no-unsafe-any
303-
return {
303+
const normalized = {
304304
...event,
305305
...(event.breadcrumbs && {
306306
breadcrumbs: event.breadcrumbs.map(b => ({
@@ -320,6 +320,17 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
320320
extra: normalize(event.extra, depth),
321321
}),
322322
};
323+
// event.contexts.trace stores information about a Transaction. Similarly,
324+
// event.spans[] stores information about child Spans. Given that a
325+
// Transaction is conceptually a Span, normalization should apply to both
326+
// Transactions and Spans consistently.
327+
// For now the decision is to skip normalization of Transactions and Spans,
328+
// so this block overwrites the normalized event to add back the original
329+
// Transaction information prior to normalization.
330+
if (event.contexts && event.contexts.trace) {
331+
normalized.contexts.trace = event.contexts.trace;
332+
}
333+
return normalized;
323334
}
324335

325336
/**

packages/core/test/lib/base.test.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Hub, Scope } from '@sentry/hub';
2-
import { Event, Severity } from '@sentry/types';
2+
import { Event, Severity, Span } from '@sentry/types';
33
import { SentryError } from '@sentry/utils';
44

55
import { TestBackend } from '../mocks/backend';
@@ -570,6 +570,54 @@ describe('BaseClient', () => {
570570
});
571571
});
572572

573+
test('normalization applies to Transaction and Span consistently', () => {
574+
expect.assertions(1);
575+
const client = new TestClient({ dsn: PUBLIC_DSN });
576+
const transaction: Event = {
577+
contexts: {
578+
trace: {
579+
data: { _sentry_web_vitals: { LCP: { value: 99.9 } } },
580+
op: 'pageload',
581+
span_id: 'a3df84a60c2e4e76',
582+
trace_id: '86f39e84263a4de99c326acab3bfe3bd',
583+
},
584+
},
585+
event_id: '972f45b826a248bba98e990878a177e1',
586+
spans: [
587+
({
588+
data: { _sentry_extra_metrics: { M1: { value: 1 }, M2: { value: 2 } } },
589+
description: 'first-paint',
590+
endTimestamp: 1591603196.637835,
591+
op: 'paint',
592+
parentSpanId: 'a3df84a60c2e4e76',
593+
spanId: '9e15bf99fbe4bc80',
594+
startTimestamp: 1591603196.637835,
595+
traceId: '86f39e84263a4de99c326acab3bfe3bd',
596+
} as any) as Span, // `as any` to bypass linter https://palantir.github.io/tslint/rules/no-object-literal-type-assertion/
597+
({
598+
description: 'first-contentful-paint',
599+
endTimestamp: 1591603196.637835,
600+
op: 'paint',
601+
parentSpanId: 'a3df84a60c2e4e76',
602+
spanId: 'aa554c1f506b0783',
603+
startTimestamp: 1591603196.637835,
604+
traceId: '86f39e84263a4de99c326acab3bfe3bd',
605+
} as any) as Span,
606+
],
607+
start_timestamp: 1591603196.614865,
608+
timestamp: 1591603196.728485,
609+
transaction: '/',
610+
type: 'transaction',
611+
};
612+
// To be consistent, normalization could apply either to both transactions
613+
// and spans, or to none. So far the decision is to skip normalization for
614+
// both, such that the expected normalizedTransaction is the same as the
615+
// input transaction.
616+
const normalizedTransaction = JSON.parse(JSON.stringify(transaction)); // deep-copy
617+
client.captureEvent(transaction);
618+
expect(TestBackend.instance!.event!).toEqual(normalizedTransaction);
619+
});
620+
573621
test('calls beforeSend and uses original event without any changes', () => {
574622
expect.assertions(1);
575623
const beforeSend = jest.fn(event => event);

0 commit comments

Comments
 (0)