Skip to content

Commit 1c4eabf

Browse files
feat: Add parentSpanIsAlwaysRootSpan is true by default (#4084)
1 parent 8d97167 commit 1c4eabf

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
### Changes
2323

24+
- Set `parentSpanIsAlwaysRootSpan` to `true` to make parent of network requests predictable ([#4084](https://github.com/getsentry/sentry-react-native/pull/4084))
2425
- Remove deprecated `enableSpotlight` and `spotlightSidecarUrl` ([#4086](https://github.com/getsentry/sentry-react-native/pull/4086))
2526
- `tracePropagationTargets` defaults to all targets on mobile and same origin on the web ([#4083](https://github.com/getsentry/sentry-react-native/pull/4083))
2627
- Move `_experiments.profilesSampleRate` to `profilesSampleRate` root options object [#3851](https://github.com/getsentry/sentry-react-native/pull/3851))

packages/core/src/js/client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export class ReactNativeClient extends BaseClient<ReactNativeClientOptions> {
4040
ignoreRequireCycleLogs();
4141
options._metadata = options._metadata || {};
4242
options._metadata.sdk = options._metadata.sdk || defaultSdkInfo;
43+
// We default this to true, as it is the safer scenario
44+
options.parentSpanIsAlwaysRootSpan =
45+
options.parentSpanIsAlwaysRootSpan === undefined ? true : options.parentSpanIsAlwaysRootSpan;
4346
super(options);
4447

4548
this._outcomesBuffer = [];

packages/core/test/client.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,25 @@ describe('Tests ReactNativeClient', () => {
356356
});
357357
});
358358

359+
describe('parentSpanIsAlwaysRootSpan', () => {
360+
it('default is true', () => {
361+
const client = new ReactNativeClient({
362+
...DEFAULT_OPTIONS,
363+
dsn: EXAMPLE_DSN,
364+
});
365+
expect(client.getOptions().parentSpanIsAlwaysRootSpan).toBe(true);
366+
});
367+
368+
it('can be set to false', () => {
369+
const client = new ReactNativeClient({
370+
...DEFAULT_OPTIONS,
371+
dsn: EXAMPLE_DSN,
372+
parentSpanIsAlwaysRootSpan: false,
373+
});
374+
expect(client.getOptions().parentSpanIsAlwaysRootSpan).toBe(false);
375+
});
376+
});
377+
359378
describe('envelopeHeader SdkInfo', () => {
360379
let mockTransportSend: jest.Mock;
361380
let client: ReactNativeClient;

packages/core/test/trace.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { setCurrentClient, spanToJSON, startSpan } from '@sentry/core';
2+
3+
import { getDefaultTestClientOptions, TestClient } from './mocks/client';
4+
5+
describe('parentSpanIsAlwaysRootSpan', () => {
6+
let client: TestClient;
7+
8+
it('creates a span as child of root span if parentSpanIsAlwaysRootSpan=true', () => {
9+
const options = getDefaultTestClientOptions({
10+
tracesSampleRate: 1,
11+
parentSpanIsAlwaysRootSpan: true,
12+
});
13+
client = new TestClient(options);
14+
setCurrentClient(client);
15+
client.init();
16+
17+
startSpan({ name: 'parent span' }, span => {
18+
expect(spanToJSON(span).parent_span_id).toBe(undefined);
19+
startSpan({ name: 'child span' }, childSpan => {
20+
expect(spanToJSON(childSpan).parent_span_id).toBe(span.spanContext().spanId);
21+
startSpan({ name: 'grand child span' }, grandChildSpan => {
22+
expect(spanToJSON(grandChildSpan).parent_span_id).toBe(span.spanContext().spanId);
23+
});
24+
});
25+
});
26+
});
27+
28+
it('does not creates a span as child of root span if parentSpanIsAlwaysRootSpan=false', () => {
29+
const options = getDefaultTestClientOptions({
30+
tracesSampleRate: 1,
31+
parentSpanIsAlwaysRootSpan: false,
32+
});
33+
client = new TestClient(options);
34+
setCurrentClient(client);
35+
client.init();
36+
37+
startSpan({ name: 'parent span' }, span => {
38+
expect(spanToJSON(span).parent_span_id).toBe(undefined);
39+
startSpan({ name: 'child span' }, childSpan => {
40+
expect(spanToJSON(childSpan).parent_span_id).toBe(span.spanContext().spanId);
41+
startSpan({ name: 'grand child span' }, grandChildSpan => {
42+
expect(spanToJSON(grandChildSpan).parent_span_id).toBe(childSpan.spanContext().spanId);
43+
});
44+
});
45+
});
46+
});
47+
});

0 commit comments

Comments
 (0)