Skip to content

Commit 79c0227

Browse files
committed
Add trace context to all error events
1 parent f013bca commit 79c0227

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

packages/core/src/baseclient.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type {
1515
Integration,
1616
IntegrationClass,
1717
Outcome,
18+
PropagationContext,
1819
SdkMetadata,
1920
Session,
2021
SessionAggregates,
@@ -29,6 +30,7 @@ import {
2930
addItemToEnvelope,
3031
checkOrSetAlreadyCaught,
3132
createAttachmentEnvelopeItem,
33+
dropUndefinedKeys,
3234
isPlainObject,
3335
isPrimitive,
3436
isThenable,
@@ -41,6 +43,7 @@ import {
4143
} from '@sentry/utils';
4244

4345
import { getEnvelopeEndpointWithUrlEncodedAuth } from './api';
46+
import { DEFAULT_ENVIRONMENT } from './constants';
4447
import { createEventEnvelope, createSessionEnvelope } from './envelope';
4548
import type { IntegrationIndex } from './integration';
4649
import { setupIntegration, setupIntegrations } from './integration';
@@ -507,7 +510,49 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
507510
if (!hint.integrations && integrations.length > 0) {
508511
hint.integrations = integrations;
509512
}
510-
return prepareEvent(options, event, hint, scope);
513+
return prepareEvent(options, event, hint, scope).then(evt => {
514+
if (evt === null) {
515+
return evt;
516+
}
517+
518+
// If a trace context is not set on the event, we use the propagationContext set on the event to
519+
// generate a trace context. If the propagationContext does not have a dynamic sampling context, we
520+
// also generate one for it.
521+
const { propagationContext } = evt.sdkProcessingMetadata || {};
522+
const trace = evt.contexts && evt.contexts.trace;
523+
if (!trace && propagationContext) {
524+
const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext as PropagationContext;
525+
evt.contexts = {
526+
trace: {
527+
trace_id,
528+
span_id: spanId,
529+
parent_span_id: parentSpanId,
530+
},
531+
...evt.contexts,
532+
};
533+
534+
const { publicKey: public_key } = this.getDsn() || {};
535+
const { segment: user_segment } = (scope && scope.getUser()) || {};
536+
537+
let dynamicSamplingContext = dsc;
538+
if (!dsc) {
539+
dynamicSamplingContext = dropUndefinedKeys({
540+
environment: options.environment || DEFAULT_ENVIRONMENT,
541+
release: options.release,
542+
user_segment,
543+
public_key,
544+
trace_id,
545+
});
546+
this.emit && this.emit('createDsc', dynamicSamplingContext);
547+
}
548+
549+
evt.sdkProcessingMetadata = {
550+
dynamicSamplingContext,
551+
...evt.sdkProcessingMetadata,
552+
};
553+
}
554+
return evt;
555+
});
511556
}
512557

513558
/**

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,28 @@ describe('BaseClient', () => {
492492
);
493493
});
494494

495+
test('it adds a trace context all events', () => {
496+
expect.assertions(1);
497+
498+
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN });
499+
const client = new TestClient(options);
500+
const scope = new Scope();
501+
502+
client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope);
503+
504+
expect(TestClient.instance!.event!).toEqual(
505+
expect.objectContaining({
506+
contexts: {
507+
trace: {
508+
parent_span_id: undefined,
509+
span_id: expect.any(String),
510+
trace_id: expect.any(String),
511+
},
512+
},
513+
}),
514+
);
515+
});
516+
495517
test('adds `event_id` from hint if available', () => {
496518
expect.assertions(1);
497519

0 commit comments

Comments
 (0)