diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js
index 56c0e05a269c..85a9847e1c3f 100644
--- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js
+++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js
@@ -1,6 +1,5 @@
Sentry.getCurrentScope().setPropagationContext({
parentSpanId: '1234567890123456',
- spanId: '123456789012345x',
traceId: '12345678901234567890123456789012',
});
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js
new file mode 100644
index 000000000000..c026daa1eed9
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js
@@ -0,0 +1,12 @@
+import * as Sentry from '@sentry/browser';
+
+window.Sentry = Sentry;
+
+Sentry.init({
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ integrations: integrations => {
+ integrations.push(Sentry.browserTracingIntegration());
+ return integrations.filter(i => i.name !== 'BrowserSession');
+ },
+ tracesSampleRate: 0,
+});
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js
new file mode 100644
index 000000000000..b7d62f8cfb95
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js
@@ -0,0 +1,2 @@
+Sentry.captureException(new Error('test error'));
+Sentry.captureException(new Error('test error 2'));
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html
new file mode 100644
index 000000000000..22d155bf8648
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts
new file mode 100644
index 000000000000..5bed055dbc0a
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts
@@ -0,0 +1,35 @@
+import { expect } from '@playwright/test';
+import type { Event } from '@sentry/browser';
+import { sentryTest } from '../../../../utils/fixtures';
+import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers';
+
+sentryTest('errors in TwP mode have same trace ID & span IDs', async ({ getLocalTestUrl, page }) => {
+ if (shouldSkipTracingTest()) {
+ sentryTest.skip();
+ }
+
+ const traceId = '12312012123120121231201212312012';
+ const spanId = '1121201211212012';
+
+ const url = await getLocalTestUrl({ testDir: __dirname });
+ const [event1, event2] = await getMultipleSentryEnvelopeRequests(page, 2, { url });
+
+ // Ensure these are the actual errors we care about
+ expect(event1.exception?.values?.[0].value).toContain('test error');
+ expect(event2.exception?.values?.[0].value).toContain('test error');
+
+ const contexts1 = event1.contexts;
+ const { trace_id: traceId1, span_id: spanId1 } = contexts1?.trace || {};
+ expect(traceId1).toEqual(traceId);
+
+ // Span ID is a virtual span, not the propagated one
+ expect(spanId1).not.toEqual(spanId);
+ expect(spanId1).toMatch(/^[a-f0-9]{16}$/);
+
+ const contexts2 = event2.contexts;
+ const { trace_id: traceId2, span_id: spanId2 } = contexts2?.trace || {};
+ expect(traceId2).toEqual(traceId);
+ expect(spanId2).toMatch(/^[a-f0-9]{16}$/);
+
+ expect(spanId2).toEqual(spanId1);
+});
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js
new file mode 100644
index 000000000000..c026daa1eed9
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js
@@ -0,0 +1,12 @@
+import * as Sentry from '@sentry/browser';
+
+window.Sentry = Sentry;
+
+Sentry.init({
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ integrations: integrations => {
+ integrations.push(Sentry.browserTracingIntegration());
+ return integrations.filter(i => i.name !== 'BrowserSession');
+ },
+ tracesSampleRate: 0,
+});
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js
new file mode 100644
index 000000000000..b7d62f8cfb95
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js
@@ -0,0 +1,2 @@
+Sentry.captureException(new Error('test error'));
+Sentry.captureException(new Error('test error 2'));
diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts
new file mode 100644
index 000000000000..3048de92b2f1
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts
@@ -0,0 +1,30 @@
+import { expect } from '@playwright/test';
+import type { Event } from '@sentry/browser';
+import { sentryTest } from '../../../../utils/fixtures';
+import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers';
+
+sentryTest('errors in TwP mode have same trace ID & span IDs', async ({ getLocalTestUrl, page }) => {
+ if (shouldSkipTracingTest()) {
+ sentryTest.skip();
+ }
+
+ const url = await getLocalTestUrl({ testDir: __dirname });
+ const [event1, event2] = await getMultipleSentryEnvelopeRequests(page, 2, { url });
+
+ // Ensure these are the actual errors we care about
+ expect(event1.exception?.values?.[0].value).toContain('test error');
+ expect(event2.exception?.values?.[0].value).toContain('test error');
+
+ const contexts1 = event1.contexts;
+ const { trace_id: traceId1, span_id: spanId1 } = contexts1?.trace || {};
+ expect(traceId1).toMatch(/^[a-f0-9]{32}$/);
+ expect(spanId1).toMatch(/^[a-f0-9]{16}$/);
+
+ const contexts2 = event2.contexts;
+ const { trace_id: traceId2, span_id: spanId2 } = contexts2?.trace || {};
+ expect(traceId2).toMatch(/^[a-f0-9]{32}$/);
+ expect(spanId2).toMatch(/^[a-f0-9]{16}$/);
+
+ expect(traceId2).toEqual(traceId1);
+ expect(spanId2).toEqual(spanId1);
+});
diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts
index e352fff5c02c..9275f9fe4505 100644
--- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts
+++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts
@@ -10,7 +10,6 @@ Sentry.init({
Sentry.getCurrentScope().setPropagationContext({
parentSpanId: '1234567890123456',
- spanId: '123456789012345x',
traceId: '12345678901234567890123456789012',
});
diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts
index 7c4f702f5df8..cbd2dd023f37 100644
--- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts
+++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts
@@ -11,7 +11,6 @@ Sentry.init({
Sentry.withScope(scope => {
scope.setPropagationContext({
parentSpanId: '1234567890123456',
- spanId: '123456789012345x',
traceId: '12345678901234567890123456789012',
});
diff --git a/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts b/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts
index 9abb7b1a631c..d4447255bf51 100644
--- a/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts
+++ b/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts
@@ -5,6 +5,7 @@ describe('errors in TwP mode have same trace in trace context and getTraceData()
cleanupChildProcesses();
});
+ // In a request handler, the spanId is consistent inside of the request
test('in incoming request', done => {
createRunner(__dirname, 'server.js')
.expect({
@@ -30,6 +31,7 @@ describe('errors in TwP mode have same trace in trace context and getTraceData()
.makeRequest('get', '/test');
});
+ // Outside of a request handler, the spanId is random
test('outside of a request handler', done => {
createRunner(__dirname, 'no-server.js')
.expect({
@@ -41,11 +43,18 @@ describe('errors in TwP mode have same trace in trace context and getTraceData()
const traceData = contexts?.traceData || {};
- expect(traceData['sentry-trace']).toEqual(`${trace_id}-${span_id}`);
+ expect(traceData['sentry-trace']).toMatch(/^[a-f0-9]{32}-[a-f0-9]{16}$/);
+ expect(traceData['sentry-trace']).toContain(`${trace_id}-`);
+ // span_id is a random span ID
+ expect(traceData['sentry-trace']).not.toContain(span_id);
+
expect(traceData.baggage).toContain(`sentry-trace_id=${trace_id}`);
expect(traceData.baggage).not.toContain('sentry-sampled=');
- expect(traceData.metaTags).toContain(``);
+ expect(traceData.metaTags).toMatch(//);
+ expect(traceData.metaTags).toContain(` {
scope.setPropagationContext({
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
parentSpanId: '6e0c63257de34c93',
- spanId: '6e0c63257de34c92',
sampled: true,
});
@@ -59,7 +58,7 @@ describe('SentryPropagator', () => {
'sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b',
].sort(),
);
- expect(carrier[SENTRY_TRACE_HEADER]).toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1');
+ expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}-1/);
});
});
@@ -68,7 +67,6 @@ describe('SentryPropagator', () => {
scope.setPropagationContext({
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
parentSpanId: '6e0c63257de34c93',
- spanId: '6e0c63257de34c92',
sampled: true,
dsc: {
transaction: 'sampled-transaction',
@@ -96,7 +94,7 @@ describe('SentryPropagator', () => {
'sentry-replay_id=dsc_replay_id',
].sort(),
);
- expect(carrier[SENTRY_TRACE_HEADER]).toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1');
+ expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}-1/);
});
});
@@ -322,7 +320,6 @@ describe('SentryPropagator', () => {
scope.setPropagationContext({
traceId: 'TRACE_ID',
parentSpanId: 'PARENT_SPAN_ID',
- spanId: 'SPAN_ID',
sampled: true,
});
@@ -362,7 +359,6 @@ describe('SentryPropagator', () => {
scope.setPropagationContext({
traceId: 'TRACE_ID',
parentSpanId: 'PARENT_SPAN_ID',
- spanId: 'SPAN_ID',
sampled: true,
});
@@ -399,7 +395,6 @@ describe('SentryPropagator', () => {
scope.setPropagationContext({
traceId: 'TRACE_ID',
parentSpanId: 'PARENT_SPAN_ID',
- spanId: 'SPAN_ID',
sampled: true,
});
@@ -601,7 +596,6 @@ describe('SentryPropagator', () => {
const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter);
expect(trace.getSpanContext(context)).toEqual(undefined);
expect(getCurrentScope().getPropagationContext()).toEqual({
- spanId: expect.stringMatching(/[a-f0-9]{16}/),
traceId: expect.stringMatching(/[a-f0-9]{32}/),
});
});
@@ -652,7 +646,6 @@ describe('SentryPropagator', () => {
const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter);
expect(trace.getSpanContext(context)).toEqual(undefined);
expect(getCurrentScope().getPropagationContext()).toEqual({
- spanId: expect.stringMatching(/[a-f0-9]{16}/),
traceId: expect.stringMatching(/[a-f0-9]{32}/),
});
});
diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts
index 6852b8b40988..cbded44a6139 100644
--- a/packages/opentelemetry/test/trace.test.ts
+++ b/packages/opentelemetry/test/trace.test.ts
@@ -1545,8 +1545,6 @@ describe('continueTrace', () => {
});
expect(scope.getPropagationContext()).toEqual({
- sampled: undefined,
- spanId: expect.any(String),
traceId: expect.any(String),
});
@@ -1554,7 +1552,7 @@ describe('continueTrace', () => {
});
it('works with trace data', () => {
- const scope = continueTrace(
+ continueTrace(
{
sentryTrace: '12312012123120121231201212312012-1121201211212012-0',
baggage: undefined,
@@ -1570,21 +1568,12 @@ describe('continueTrace', () => {
});
expect(getSamplingDecision(span.spanContext())).toBe(false);
expect(spanIsSampled(span)).toBe(false);
-
- return getCurrentScope();
},
);
-
- expect(scope.getPropagationContext()).toEqual({
- spanId: expect.any(String),
- traceId: expect.any(String),
- });
-
- expect(scope.getScopeData().sdkProcessingMetadata).toEqual({});
});
it('works with trace & baggage data', () => {
- const scope = continueTrace(
+ continueTrace(
{
sentryTrace: '12312012123120121231201212312012-1121201211212012-1',
baggage: 'sentry-version=1.0,sentry-environment=production',
@@ -1600,21 +1589,12 @@ describe('continueTrace', () => {
});
expect(getSamplingDecision(span.spanContext())).toBe(true);
expect(spanIsSampled(span)).toBe(true);
-
- return getCurrentScope();
},
);
-
- expect(scope.getPropagationContext()).toEqual({
- spanId: expect.any(String),
- traceId: expect.any(String),
- });
-
- expect(scope.getScopeData().sdkProcessingMetadata).toEqual({});
});
it('works with trace & 3rd party baggage data', () => {
- const scope = continueTrace(
+ continueTrace(
{
sentryTrace: '12312012123120121231201212312012-1121201211212012-1',
baggage: 'sentry-version=1.0,sentry-environment=production,dogs=great,cats=boring',
@@ -1630,16 +1610,8 @@ describe('continueTrace', () => {
});
expect(getSamplingDecision(span.spanContext())).toBe(true);
expect(spanIsSampled(span)).toBe(true);
-
- return getCurrentScope();
},
);
-
- expect(scope.getPropagationContext()).toEqual({
- spanId: expect.any(String),
- traceId: expect.any(String),
- });
- expect(scope.getScopeData().sdkProcessingMetadata).toEqual({});
});
it('returns response of callback', () => {
diff --git a/packages/opentelemetry/test/utils/getTraceData.test.ts b/packages/opentelemetry/test/utils/getTraceData.test.ts
index e0f2270d8e22..f18f1c307639 100644
--- a/packages/opentelemetry/test/utils/getTraceData.test.ts
+++ b/packages/opentelemetry/test/utils/getTraceData.test.ts
@@ -55,7 +55,6 @@ describe('getTraceData', () => {
getCurrentScope().setPropagationContext({
traceId: '12345678901234567890123456789012',
sampled: true,
- spanId: '1234567890123456',
dsc: {
environment: 'staging',
public_key: 'key',
@@ -65,10 +64,10 @@ describe('getTraceData', () => {
const traceData = getTraceData();
- expect(traceData).toEqual({
- 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
- baggage: 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012',
- });
+ expect(traceData['sentry-trace']).toMatch(/^12345678901234567890123456789012-[a-f0-9]{16}-1$/);
+ expect(traceData.baggage).toEqual(
+ 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012',
+ );
});
it('works with an span with frozen DSC in traceState', () => {