Skip to content
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

feat(replay): Stop replays when a segment could not be sent #6765

Merged
merged 1 commit into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions packages/replay/src/replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -824,10 +824,16 @@ export class ReplayContainer implements ReplayContainerInterface {
timestamp: new Date().getTime(),
});
} catch (err) {
this._handleException(err);

if (err instanceof RateLimitError) {
this._handleRateLimit(err.rateLimits);
return;
}
this._handleException(err);

// This means we retried 3 times, and all of them failed
// In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments
this.stop();
}
}

Expand All @@ -837,8 +843,7 @@ export class ReplayContainer implements ReplayContainerInterface {
*/
private _flush: () => Promise<void> = async () => {
if (!this._isEnabled) {
// This is just a precaution, there should be no listeners that would
// cause a flush.
// This can happen if e.g. the replay was stopped because of exceeding the retry limit
return;
}

Expand Down
12 changes: 12 additions & 0 deletions packages/replay/test/integration/sendReplayEvent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,5 +428,17 @@ describe('Integration | sendReplayEvent', () => {

// segmentId increases despite error
expect(replay.session?.segmentId).toBe(1);

// Replay should be completely stopped now
expect(replay.isEnabled()).toBe(false);

// Events are ignored now, because we stopped
mockRecord._emitter(TEST_EVENT);
await advanceTimers(DEFAULT_FLUSH_MIN_DELAY);
expect(mockSendReplayRequest).toHaveBeenCalledTimes(4);
});

// NOTE: If you add a test after the last one, make sure to adjust the test setup
// As this ends with a `stopped()` replay, which may prevent future tests from working
// Sadly, fixing this turned out to be much more annoying than expected, so leaving this warning here for now
});