Skip to content

fix(browser): Ensure request from diagnoseSdkConnectivity doesn't create span #17280

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 1, 2025
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [Sentry.browserTracingIntegration({ idleTimeout: 3000, childSpanTimeout: 3000 })],
tracesSampleRate: 1,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Sentry.diagnoseSdkConnectivity().then(res => console.log('SDK connectivity:', res));
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../utils/fixtures';
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../utils/helpers';

sentryTest('makes a call to sentry.io to diagnose SDK connectivity', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
sentryTest.skip();
}

const pageloadRequestPromise = waitForTransactionRequest(page, e => e.contexts?.trace?.op === 'pageload');

// mock sdk connectivity url to avoid making actual request to sentry.io
page.route('**/api/4509632503087104/envelope/**/*', route => {
return route.fulfill({
status: 200,
body: '{}',
});
});

const diagnoseMessagePromise = new Promise<string>(resolve => {
page.on('console', msg => {
if (msg.text().includes('SDK connectivity:')) {
resolve(msg.text());
}
});
});

const url = await getLocalTestUrl({ testDir: __dirname });
await page.goto(url);

const pageLoadEvent = envelopeRequestParser(await pageloadRequestPromise);

// udnefined is expected and means the request was successful
expect(await diagnoseMessagePromise).toEqual('SDK connectivity: undefined');

// the request to sentry.io should not be traced, hence no http.client span should be sent.
const httpClientSpans = pageLoadEvent.spans?.filter(s => s.op === 'http.client');
expect(httpClientSpans).toHaveLength(0);

// no fetch breadcrumb should be sent (only breadcrumb for the console log)
expect(pageLoadEvent.breadcrumbs).toEqual([
expect.objectContaining({
category: 'console',
message: 'SDK connectivity: undefined',
}),
]);
});
32 changes: 17 additions & 15 deletions packages/browser/src/diagnose-sdk.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getClient } from '@sentry/core';
import { getClient, suppressTracing } from '@sentry/core';

/**
* A function to diagnose why the SDK might not be successfully sending data.
Expand All @@ -23,20 +23,22 @@ export async function diagnoseSdkConnectivity(): Promise<
}

try {
// If fetch throws, there is likely an ad blocker active or there are other connective issues.
await fetch(
// We are using the
// - "sentry-sdks" org with id 447951 not to pollute any actual organizations.
// - "diagnose-sdk-connectivity" project with id 4509632503087104
// - the public key of said org/project, which is disabled in the project settings
// => this DSN: https://[email protected]/4509632503087104 (i.e. disabled)
'https://o447951.ingest.sentry.io/api/4509632503087104/envelope/?sentry_version=7&sentry_key=c1dfb07d783ad5325c245c1fd3725390&sentry_client=sentry.javascript.browser%2F1.33.7',
{
body: '{}',
method: 'POST',
mode: 'cors',
credentials: 'omit',
},
await suppressTracing(() =>
// If fetch throws, there is likely an ad blocker active or there are other connective issues.
fetch(
// We are using the
// - "sentry-sdks" org with id 447951 not to pollute any actual organizations.
// - "diagnose-sdk-connectivity" project with id 4509632503087104
// - the public key of said org/project, which is disabled in the project settings
// => this DSN: https://[email protected]/4509632503087104 (i.e. disabled)
'https://o447951.ingest.sentry.io/api/4509632503087104/envelope/?sentry_version=7&sentry_key=c1dfb07d783ad5325c245c1fd3725390&sentry_client=sentry.javascript.browser%2F1.33.7',
{
body: '{}',
method: 'POST',
mode: 'cors',
credentials: 'omit',
},
),
);
} catch {
return 'sentry-unreachable';
Expand Down
14 changes: 14 additions & 0 deletions packages/browser/test/diagnose-sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,18 @@ describe('diagnoseSdkConnectivity', () => {
credentials: 'omit',
});
});

it('calls suppressTracing to avoid tracing the fetch call to sentry', async () => {
const suppressTracingSpy = vi.spyOn(sentryCore, 'suppressTracing');

const mockClient: Partial<Client> = {
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
};
mockGetClient.mockReturnValue(mockClient);
mockFetch.mockResolvedValue(new Response('{}', { status: 200 }));

await diagnoseSdkConnectivity();

expect(suppressTracingSpy).toHaveBeenCalledTimes(1);
});
});
Loading