Skip to content

Commit f52787f

Browse files
nicohrubecclaude
andauthored
test(tanstackstart-react): Initialize Sentry from a dedicated client init file (#21397)
Changes the setup to a dedicated init file that is imported first to ensure that Sentry init is run first. This guarantees `Sentry.init()` runs before any other import's side effects. Fixes #21088 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4b75699 commit f52787f

8 files changed

Lines changed: 80 additions & 20 deletions

File tree

‎dev-packages/e2e-tests/test-applications/tanstackstart-react-cloudflare/src/client.tsx‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
import * as Sentry from '@sentry/browser';
1+
// Imported first so Sentry.init() runs before any other import's side effects.
2+
import './instrument.client';
3+
import './early-side-effect';
24
import { StartClient } from '@tanstack/react-start/client';
35
import { StrictMode, startTransition } from 'react';
46
import { hydrateRoot } from 'react-dom/client';
57

6-
Sentry.init({
7-
environment: 'qa',
8-
dsn: 'https://public@dsn.ingest.sentry.io/1337',
9-
tracesSampleRate: 1.0,
10-
release: 'e2e-test',
11-
tunnel: 'http://localhost:3031/',
12-
});
13-
148
console.log('early-breadcrumb-from-client-entry');
159

1610
if (window.location.pathname === '/crash-before-hydration') {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Simulates a third-party import whose side effects run at module-evaluation time,
2+
// i.e. before the client entry's body (and before hydration).
3+
console.log('early-breadcrumb-from-imported-module');
4+
5+
if (typeof window !== 'undefined' && window.location.pathname === '/crash-in-imported-module') {
6+
throw new Error('Imported Module Side Effect Crash');
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
Sentry.init({
4+
environment: 'qa',
5+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
6+
tracesSampleRate: 1.0,
7+
release: 'e2e-test',
8+
tunnel: 'http://localhost:3031/',
9+
});

‎dev-packages/e2e-tests/test-applications/tanstackstart-react-cloudflare/tests/early-init.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,24 @@ test('should capture errors thrown in client entry before hydration', async ({ p
2121

2222
expect(consoleBreadcrumbs?.length).toBeGreaterThanOrEqual(1);
2323
});
24+
25+
test('should capture errors thrown in a module imported by the client entry before hydration', async ({ page }) => {
26+
const errorEventPromise = waitForError('tanstackstart-react-cloudflare', errorEvent => {
27+
return errorEvent?.exception?.values?.[0]?.value === 'Imported Module Side Effect Crash';
28+
});
29+
30+
await page.goto('/crash-in-imported-module');
31+
32+
const errorEvent = await errorEventPromise;
33+
34+
expect(errorEvent.exception?.values?.[0]).toMatchObject({
35+
type: 'Error',
36+
value: 'Imported Module Side Effect Crash',
37+
});
38+
39+
const consoleBreadcrumbs = errorEvent.breadcrumbs?.filter(
40+
b => b.category === 'console' && b.message?.includes('early-breadcrumb-from-imported-module'),
41+
);
42+
43+
expect(consoleBreadcrumbs?.length).toBeGreaterThanOrEqual(1);
44+
});

‎dev-packages/e2e-tests/test-applications/tanstackstart-react/src/client.tsx‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
1-
import * as Sentry from '@sentry/tanstackstart-react';
1+
// Imported first so Sentry.init() runs before any other import's side effects.
2+
import './instrument.client';
3+
import './early-side-effect';
24
import { StartClient } from '@tanstack/react-start/client';
35
import { StrictMode, startTransition } from 'react';
46
import { hydrateRoot } from 'react-dom/client';
57

6-
Sentry.init({
7-
environment: 'qa', // dynamic sampling bias to keep transactions
8-
dsn: __APP_DSN__,
9-
// We recommend adjusting this value in production, or using tracesSampler
10-
// for finer control
11-
tracesSampleRate: 1.0,
12-
release: 'e2e-test',
13-
tunnel: __APP_TUNNEL__,
14-
});
15-
168
console.log('early-breadcrumb-from-client-entry');
179

1810
if (window.location.pathname === '/crash-before-hydration') {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Simulates a third-party import whose side effects run at module-evaluation time,
2+
// i.e. before the client entry's body (and before hydration).
3+
console.log('early-breadcrumb-from-imported-module');
4+
5+
if (typeof window !== 'undefined' && window.location.pathname === '/crash-in-imported-module') {
6+
throw new Error('Imported Module Side Effect Crash');
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as Sentry from '@sentry/tanstackstart-react';
2+
3+
Sentry.init({
4+
environment: 'qa', // dynamic sampling bias to keep transactions
5+
dsn: __APP_DSN__,
6+
tracesSampleRate: 1.0,
7+
release: 'e2e-test',
8+
tunnel: __APP_TUNNEL__,
9+
});

‎dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/early-init.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,24 @@ test('should capture errors thrown in client entry before hydration', async ({ p
2626

2727
expect(consoleBreadcrumbs?.length).toBeGreaterThanOrEqual(1);
2828
});
29+
30+
test('should capture errors thrown in a module imported by the client entry before hydration', async ({ page }) => {
31+
const errorEventPromise = waitForError('tanstackstart-react', errorEvent => {
32+
return errorEvent?.exception?.values?.[0]?.value === 'Imported Module Side Effect Crash';
33+
});
34+
35+
await page.goto('/crash-in-imported-module');
36+
37+
const errorEvent = await errorEventPromise;
38+
39+
expect(errorEvent.exception?.values?.[0]).toMatchObject({
40+
type: 'Error',
41+
value: 'Imported Module Side Effect Crash',
42+
});
43+
44+
const consoleBreadcrumbs = errorEvent.breadcrumbs?.filter(
45+
b => b.category === 'console' && b.message?.includes('early-breadcrumb-from-imported-module'),
46+
);
47+
48+
expect(consoleBreadcrumbs?.length).toBeGreaterThanOrEqual(1);
49+
});

0 commit comments

Comments
 (0)