fix(replay): detect and report rrweb silent initialization failure#3174
Merged
TueHaulund merged 4 commits intomainfrom Feb 28, 2026
Merged
fix(replay): detect and report rrweb silent initialization failure#3174TueHaulund merged 4 commits intomainfrom
TueHaulund merged 4 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Contributor
|
Size Change: +652 B (+0.01%) Total Size: 6.69 MB
ℹ️ View Unchanged
|
rrweb's record() wraps its entire body in a try-catch that silently swallows errors via console.warn and returns undefined. The SDK was not checking this return value, so it would report recording as active while rrweb never actually initialized - resulting in zero recording data being captured or flushed. Check the return value of rrwebRecord() in _startRecorder() and bail out with a new RRWEB_ERROR status if it fails. This makes the failure visible in SDK debug properties instead of silently losing data.
85efc59 to
01d66fb
Compare
pauldambra
reviewed
Feb 28, 2026
packages/browser/src/extensions/replay/external/lazy-loaded-session-recorder.ts
Outdated
Show resolved
Hide resolved
pauldambra
reviewed
Feb 28, 2026
| // Replication of `record` from inside `@rrweb/record` | ||
| export type rrwebRecord = { | ||
| (options: recordOptions): () => void | ||
| (options: recordOptions): (() => void) | undefined |
Member
There was a problem hiding this comment.
i wish i'd finished moving rrweb into this monorepo... we should really make this explicit
undefined to mean error is so vague 🙈
pauldambra
approved these changes
Feb 28, 2026
Member
pauldambra
left a comment
There was a problem hiding this comment.
we should add the error state onto the debug properties
- Check _rrwebError flag directly in start() instead of redundantly setting it again, since _startRecorder() already sets the flag - Add $sdk_debug_replay_rrweb_error to debug properties
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
rrweb's
record()wraps its entire body in a try-catch that silently swallows errors (viaconsole.warn) and returnsundefined. The SDK was not checking this return value, so it would continue to reportrecording_status: activewhile rrweb never actually initialized — resulting in zero recording data being captured or flushed.Likely triggers include canvas recording with cross-origin tainted canvases (
SecurityErrorontoDataURL()), strict CSP policies, or complex DOM structures that cause rrweb to throw during initialization.Changes
types/rrweb.ts: FixedrrwebRecordreturn type to(() => void) | undefinedto match the actual upstream rrweb behavior — previously declared as() => voidwhich meant TypeScript wouldn't warn about the missing checktriggerMatching.ts: AddedRRWEB_ERRORstatus constant andrrwebErrorproperty toRecordingTriggersStatus— all three matcher functions (nullMatch,anyMatch,allMatch) check it firstlazy-loaded-session-recorder.ts: Added_rrwebErrorflag, set whenrrwebRecord()returns falsy in_startRecorder(), cleared on successful start (supports retries), passed through the status matchersessionRecordingStatus.test.ts: Tests thatRRWEB_ERRORis returned by both matchers, and that it takes precedence over sampling and active triggerslazy-sessionrecording.test.ts: Tests thatstarted === falseandstatus === 'rrweb_error'whenrrwebRecord()returnsundefined, and that recording recovers when rrweb starts successfully on retryTest plan
$recording_statusproperty showsrrweb_errorin debug events when rrweb fails to initialize