Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
> [migration guide](https://docs.sentry.io/platforms/javascript/guides/capacitor/migration/) first.
<!-- prettier-ignore-end -->

## Unreleased

### Features

- Add `strictTraceContinuation` and `orgId` options for trace continuation validation ([#1166](https://github.com/getsentry/sentry-capacitor/pull/1166))

## 3.1.0

### Dependencies
Expand Down
21 changes: 21 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ export interface BaseCapacitorOptions {
appHangTimeoutInterval?: number;


/**
* If set to `true`, the SDK will only continue a trace if the `organization ID` of the incoming trace found in the
* `baggage` header matches the `organization ID` of the current Sentry client.
*
* The client's organization ID is extracted from the DSN or can be set with the `orgId` option.
*
* If the organization IDs do not match, the SDK will start a new trace instead of continuing the incoming one.
* This is useful to prevent traces of unknown third-party services from being continued in your application.
*
* @default false
*/
strictTraceContinuation?: boolean;

/**
* The organization ID for your Sentry project.
*
* The SDK will try to extract the organization ID from the DSN. If it cannot be found, or if you need to override it,
* you can provide the ID with this option. The organization ID is used for trace propagation and for features like `strictTraceContinuation`.
*/
orgId?: `${number}` | number;

/**
* Only for Vue or Nuxt Client.
* Allows the setup of sibling specific SDK. You are still allowed to set the same parameters
Expand Down
73 changes: 73 additions & 0 deletions test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,79 @@ describe('SDK Init', () => {
});
});

test('passes strictTraceContinuation and orgId to browser options', () => {
NATIVE.platform = 'web';
const mockOriginalInit = jest.fn();

init({
dsn: 'test-dsn',
enabled: true,
strictTraceContinuation: true,
orgId: '12345',
}, mockOriginalInit);

// Wait for async operations
return new Promise<void>(resolve => {
setTimeout(() => {
expect(mockOriginalInit).toHaveBeenCalled();
const browserOptions = mockOriginalInit.mock.calls[0][0];

expect(browserOptions.strictTraceContinuation).toBe(true);
expect(browserOptions.orgId).toBe('12345');

resolve();
}, 0);
});
});

test('passes strictTraceContinuation and orgId to native options', () => {
NATIVE.platform = 'ios';
const mockOriginalInit = jest.fn();

init({
dsn: 'test-dsn',
enabled: true,
strictTraceContinuation: true,
orgId: 67890,
}, mockOriginalInit);

// Wait for async operations
return new Promise<void>(resolve => {
setTimeout(() => {
expect(NATIVE.initNativeSdk).toHaveBeenCalled();
const nativeOptions = (NATIVE.initNativeSdk as jest.Mock).mock.calls[0][0];

expect(nativeOptions.strictTraceContinuation).toBe(true);
expect(nativeOptions.orgId).toBe(67890);

resolve();
}, 0);
});
});

test('strictTraceContinuation defaults to undefined when not set', () => {
NATIVE.platform = 'web';
const mockOriginalInit = jest.fn();

init({
dsn: 'test-dsn',
enabled: true,
}, mockOriginalInit);

// Wait for async operations
return new Promise<void>(resolve => {
setTimeout(() => {
expect(mockOriginalInit).toHaveBeenCalled();
const browserOptions = mockOriginalInit.mock.calls[0][0];

expect(browserOptions.strictTraceContinuation).toBeUndefined();
expect(browserOptions.orgId).toBeUndefined();

resolve();
}, 0);
});
});

test('RewriteFrames to be added by default', async () => {
NATIVE.platform = 'web';
const mockOriginalInit = jest.fn();
Expand Down
Loading