Skip to content

Commit 4bdd979

Browse files
authored
feat(replay): Improve public Replay APIs (#13000)
1 parent b2dded8 commit 4bdd979

File tree

4 files changed

+49
-8
lines changed

4 files changed

+49
-8
lines changed

packages/replay-internal/src/integration.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ export class Replay implements Integration {
226226

227227
/**
228228
* Start a replay regardless of sampling rate. Calling this will always
229-
* create a new session. Will throw an error if replay is already in progress.
229+
* create a new session. Will log a message if replay is already in progress.
230230
*
231231
* Creates or loads a session, attaches listeners to varying events (DOM,
232232
* PerformanceObserver, Recording, Sentry SDK, etc)
@@ -235,7 +235,6 @@ export class Replay implements Integration {
235235
if (!this._replay) {
236236
return;
237237
}
238-
239238
this._replay.start();
240239
}
241240

@@ -265,13 +264,20 @@ export class Replay implements Integration {
265264

266265
/**
267266
* If not in "session" recording mode, flush event buffer which will create a new replay.
267+
* If replay is not enabled, a new session replay is started.
268268
* Unless `continueRecording` is false, the replay will continue to record and
269269
* behave as a "session"-based replay.
270270
*
271271
* Otherwise, queue up a flush.
272272
*/
273273
public flush(options?: SendBufferedReplayOptions): Promise<void> {
274-
if (!this._replay || !this._replay.isEnabled()) {
274+
if (!this._replay) {
275+
return Promise.resolve();
276+
}
277+
278+
// assuming a session should be recorded in this case
279+
if (!this._replay.isEnabled()) {
280+
this._replay.start();
275281
return Promise.resolve();
276282
}
277283

packages/replay-internal/src/replay.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,20 @@ export class ReplayContainer implements ReplayContainerInterface {
288288

289289
/**
290290
* Start a replay regardless of sampling rate. Calling this will always
291-
* create a new session. Will throw an error if replay is already in progress.
291+
* create a new session. Will log a message if replay is already in progress.
292292
*
293293
* Creates or loads a session, attaches listeners to varying events (DOM,
294294
* _performanceObserver, Recording, Sentry SDK, etc)
295295
*/
296296
public start(): void {
297297
if (this._isEnabled && this.recordingMode === 'session') {
298-
throw new Error('Replay recording is already in progress');
298+
DEBUG_BUILD && logger.info('[Replay] Recording is already in progress');
299+
return;
299300
}
300301

301302
if (this._isEnabled && this.recordingMode === 'buffer') {
302-
throw new Error('Replay buffering is in progress, call `flush()` to save the replay');
303+
DEBUG_BUILD && logger.info('[Replay] Buffering is in progress, call `flush()` to save the replay');
304+
return;
303305
}
304306

305307
logInfoNextTick('[Replay] Starting replay in session mode', this._options._experiments.traceInternals);
@@ -335,7 +337,8 @@ export class ReplayContainer implements ReplayContainerInterface {
335337
*/
336338
public startBuffering(): void {
337339
if (this._isEnabled) {
338-
throw new Error('Replay recording is already in progress');
340+
DEBUG_BUILD && logger.info('[Replay] Buffering is in progress, call `flush()` to save the replay');
341+
return;
339342
}
340343

341344
logInfoNextTick('[Replay] Starting replay in buffer mode', this._options._experiments.traceInternals);

packages/replay-internal/test/integration/flush.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as SentryBrowserUtils from '@sentry-internal/browser-utils';
99
import * as SentryUtils from '@sentry/utils';
1010

1111
import { DEFAULT_FLUSH_MIN_DELAY, MAX_REPLAY_DURATION, WINDOW } from '../../src/constants';
12+
import type { Replay } from '../../src/integration';
1213
import type { ReplayContainer } from '../../src/replay';
1314
import { clearSession } from '../../src/session/clearSession';
1415
import type { EventBuffer } from '../../src/types';
@@ -33,6 +34,7 @@ describe('Integration | flush', () => {
3334

3435
const { record: mockRecord } = mockRrweb();
3536

37+
let integration: Replay;
3638
let replay: ReplayContainer;
3739
let mockSendReplay: MockSendReplay;
3840
let mockFlush: MockFlush;
@@ -45,7 +47,7 @@ describe('Integration | flush', () => {
4547
domHandler = handler;
4648
});
4749

48-
({ replay } = await mockSdk());
50+
({ replay, integration } = await mockSdk());
4951

5052
mockSendReplay = vi.spyOn(SendReplay, 'sendReplay');
5153
mockSendReplay.mockImplementation(
@@ -484,4 +486,14 @@ describe('Integration | flush', () => {
484486
// Start again for following tests
485487
await replay.start();
486488
});
489+
490+
/**
491+
* Assuming the user wants to record a session
492+
* when calling flush() without replay being enabled
493+
*/
494+
it('starts recording a session when replay is not enabled', () => {
495+
integration.stop();
496+
integration.flush();
497+
expect(replay.isEnabled()).toBe(true);
498+
});
487499
});

packages/replay-internal/test/integration/start.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,24 @@ describe('Integration | start', () => {
4949
recordingPayloadHeader: { segment_id: 0 },
5050
});
5151
});
52+
53+
it('does not start recording once replay is already in progress', async () => {
54+
const startRecordingSpy = vi.spyOn(replay, 'startRecording').mockImplementation(() => undefined);
55+
56+
integration.start();
57+
replay.start();
58+
replay.start();
59+
60+
expect(startRecordingSpy).toHaveBeenCalledTimes(1);
61+
});
62+
63+
it('does not start buffering once replay is already in progress', async () => {
64+
const startRecordingSpy = vi.spyOn(replay, 'startRecording').mockImplementation(() => undefined);
65+
66+
integration.startBuffering();
67+
replay.startBuffering();
68+
replay.startBuffering();
69+
70+
expect(startRecordingSpy).toHaveBeenCalledTimes(1);
71+
});
5272
});

0 commit comments

Comments
 (0)