Skip to content

Commit 857a688

Browse files
committed
fix(replay): Start replay immediately, not in next tick
This should hopefully fix some race conditions...
1 parent 24dfc66 commit 857a688

File tree

15 files changed

+93
-14
lines changed

15 files changed

+93
-14
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ jobs:
761761
- loader_debug
762762
- loader_tracing
763763
- loader_replay
764+
- loader_replay_buffer
764765
- loader_tracing_replay
765766

766767
steps:

dev-packages/browser-integration-tests/loader-suites/loader/noOnLoad/replay/test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { sentryTest } from '../../../../utils/fixtures';
44
import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';
55

66
sentryTest('should capture a replay', async ({ getLocalTestUrl, page }) => {
7-
if (shouldSkipReplayTest()) {
7+
// When in buffer mode, there will not be a replay by default
8+
if (shouldSkipReplayTest() || process.env.PW_BUNDLE === 'loader_replay_buffer') {
89
sentryTest.skip();
910
}
1011

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
window.doSomethingWrong();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../../utils/fixtures';
4+
import { envelopeRequestParser, waitForErrorRequestOnUrl } from '../../../../utils/helpers';
5+
import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';
6+
7+
sentryTest('should capture a replay & attach an error', async ({ getLocalTestUrl, page }) => {
8+
if (shouldSkipReplayTest()) {
9+
sentryTest.skip();
10+
}
11+
12+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
13+
return route.fulfill({
14+
status: 200,
15+
contentType: 'application/json',
16+
body: JSON.stringify({ id: 'test-id' }),
17+
});
18+
});
19+
20+
const req = waitForReplayRequest(page);
21+
22+
const url = await getLocalTestUrl({ testDir: __dirname });
23+
const reqError = await waitForErrorRequestOnUrl(page, url);
24+
25+
const errorEventData = envelopeRequestParser(reqError);
26+
expect(errorEventData.exception?.values?.length).toBe(1);
27+
expect(errorEventData.exception?.values?.[0]?.value).toBe('window.doSomethingWrong is not a function');
28+
29+
const eventData = getReplayEvent(await req);
30+
31+
expect(eventData).toBeDefined();
32+
expect(eventData.segment_id).toBe(0);
33+
34+
expect(errorEventData.tags?.replayId).toEqual(eventData.replay_id);
35+
});

dev-packages/browser-integration-tests/loader-suites/loader/onLoad/customReplay/init.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ Sentry.onLoad(function () {
66
useCompression: false,
77
}),
88
],
9+
10+
replaysSessionSampleRate: 1,
911
});
1012
});
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
Sentry.onLoad(function () {
2-
Sentry.init({});
2+
Sentry.init({
3+
replaysSessionSampleRate: 1,
4+
});
35
});

dev-packages/browser-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"test:loader:eager": "PW_BUNDLE=loader_eager yarn test:loader",
3333
"test:loader:tracing": "PW_BUNDLE=loader_tracing yarn test:loader",
3434
"test:loader:replay": "PW_BUNDLE=loader_replay yarn test:loader",
35+
"test:loader:replay_buffer": "PW_BUNDLE=loader_replay_buffer yarn test:loader",
3536
"test:loader:full": "PW_BUNDLE=loader_tracing_replay yarn test:loader",
3637
"test:loader:debug": "PW_BUNDLE=loader_debug yarn test:loader",
3738
"test:ci": "yarn test:all --reporter='line'",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
window.doSomethingWrong();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../../utils/fixtures';
4+
import { envelopeRequestParser, waitForErrorRequestOnUrl } from '../../../../utils/helpers';
5+
import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';
6+
7+
sentryTest(
8+
'[error-mode] should capture error that happens immediately after init',
9+
async ({ getLocalTestUrl, page }) => {
10+
if (shouldSkipReplayTest()) {
11+
sentryTest.skip();
12+
}
13+
14+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
15+
return route.fulfill({
16+
status: 200,
17+
contentType: 'application/json',
18+
body: JSON.stringify({ id: 'test-id' }),
19+
});
20+
});
21+
22+
const req = waitForReplayRequest(page);
23+
24+
const url = await getLocalTestUrl({ testDir: __dirname });
25+
const reqError = await waitForErrorRequestOnUrl(page, url);
26+
27+
const errorEventData = envelopeRequestParser(reqError);
28+
expect(errorEventData.exception?.values?.length).toBe(1);
29+
expect(errorEventData.exception?.values?.[0]?.value).toBe('window.doSomethingWrong is not a function');
30+
31+
const eventData = getReplayEvent(await req);
32+
33+
expect(eventData).toBeDefined();
34+
expect(eventData.segment_id).toBe(0);
35+
36+
expect(errorEventData.tags?.replayId).toEqual(eventData.replay_id);
37+
},
38+
);

dev-packages/browser-integration-tests/utils/generatePlugin.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const BUNDLE_PATHS: Record<string, Record<string, string>> = {
5555
loader_debug: 'build/bundles/bundle.debug.min.js',
5656
loader_tracing: 'build/bundles/bundle.tracing.min.js',
5757
loader_replay: 'build/bundles/bundle.replay.min.js',
58+
loader_replay_buffer: 'build/bundles/bundle.replay.min.js',
5859
loader_tracing_replay: 'build/bundles/bundle.tracing.replay.debug.min.js',
5960
},
6061
integrations: {
@@ -96,6 +97,10 @@ export const LOADER_CONFIGS: Record<string, { options: Record<string, unknown>;
9697
options: { replaysSessionSampleRate: 1, replaysOnErrorSampleRate: 1 },
9798
lazy: false,
9899
},
100+
loader_replay_buffer: {
101+
options: { replaysSessionSampleRate: 0, replaysOnErrorSampleRate: 1 },
102+
lazy: false,
103+
},
99104
loader_tracing_replay: {
100105
options: { tracesSampleRate: 1, replaysSessionSampleRate: 1, replaysOnErrorSampleRate: 1, debug: true },
101106
lazy: false,
@@ -128,8 +133,9 @@ function generateSentryAlias(): Record<string, string> {
128133

129134
const modulePath = path.resolve(PACKAGES_DIR, packageName);
130135

131-
if (useCompiledModule && bundleKey && BUNDLE_PATHS[packageName]?.[bundleKey]) {
132-
const bundlePath = path.resolve(modulePath, BUNDLE_PATHS[packageName][bundleKey]);
136+
const bundleKeyPath = bundleKey && BUNDLE_PATHS[packageName]?.[bundleKey];
137+
if (useCompiledModule && bundleKeyPath) {
138+
const bundlePath = path.resolve(modulePath, bundleKeyPath);
133139

134140
return [packageJSON['name'], bundlePath];
135141
}

packages/replay-internal/src/integration.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,7 @@ export class Replay implements Integration {
221221
}
222222

223223
this._setup();
224-
225-
// Once upon a time, we tried to create a transaction in `setupOnce` and it would
226-
// potentially create a transaction before some native SDK integrations have run
227-
// and applied their own global event processor. An example is:
228-
// https://github.com/getsentry/sentry-javascript/blob/b47ceafbdac7f8b99093ce6023726ad4687edc48/packages/browser/src/integrations/useragent.ts
229-
//
230-
// So we call `this._initialize()` in next event loop as a workaround to wait for other
231-
// global event processors to finish. This is no longer needed, but keeping it
232-
// here to avoid any future issues.
233-
setTimeout(() => this._initialize());
224+
this._initialize();
234225
}
235226

236227
/**

0 commit comments

Comments
 (0)