Skip to content

Commit fc390a9

Browse files
fix: rrweb recorder may throw error when stopping recording after an iframe becomes cross-origin (#1695)
* fix: rrweb recorder may throw error when stopping recording after an iframe becomes cross-origin * add change set * add failure message check * Update packages/rrweb/src/record/index.ts Co-authored-by: Eoghan Murray <[email protected]> * remove settimeout --------- Co-authored-by: Eoghan Murray <[email protected]>
1 parent 4db9782 commit fc390a9

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

.changeset/nervous-actors-jam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"rrweb": patch
3+
---
4+
5+
fix: rrweb recorder may throw error when stopping recording after an iframe becomes cross-origin

packages/rrweb/src/record/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,25 @@ function record<T = eventWithTime>(
617617
);
618618
}
619619
return () => {
620-
handlers.forEach((h) => h());
620+
handlers.forEach((handler) => {
621+
try {
622+
handler();
623+
} catch (error) {
624+
const msg = String(error).toLowerCase();
625+
/**
626+
* https://github.com/rrweb-io/rrweb/pull/1695
627+
* This error can occur in a known scenario:
628+
* If an iframe is initially same-origin and observed, but later its
629+
location is changed in an opaque way to a cross-origin URL (perhaps within the iframe via its `document.location` or a redirect)
630+
* attempting to execute the handler in the stop record function will
631+
throw a "cannot access cross-origin frame" error.
632+
* This error is expected and can be safely ignored.
633+
*/
634+
if (!msg.includes('cross-origin')) {
635+
console.warn(error);
636+
}
637+
}
638+
});
621639
processedNodeManager.destroy();
622640
recording = false;
623641
unregisterErrorHandler();

packages/rrweb/test/record.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,27 @@ describe('record', function (this: ISuite) {
990990

991991
await assertSnapshot(ctx.events);
992992
});
993+
994+
it('does not throw error when stopping recording after iframe becomes cross-origin', async () => {
995+
await ctx.page.evaluate(async () => {
996+
const { record } = (window as unknown as IWindow).rrweb;
997+
const stopRecord = record({
998+
emit: (window as unknown as IWindow).emit,
999+
});
1000+
const iframe = document.createElement('iframe');
1001+
(window as any).stopRecord = stopRecord;
1002+
(window as any).iframe = iframe;
1003+
document.body.appendChild(iframe);
1004+
});
1005+
await waitForRAF(ctx.page);
1006+
await ctx.page.evaluate(async () => {
1007+
(window as any).iframe.src = 'https://www.example.com'; // Change the same origin iframe to a cross origin iframe after it's recorded
1008+
});
1009+
await waitForRAF(ctx.page);
1010+
await ctx.page.evaluate(() => {
1011+
(window as any).stopRecord?.();
1012+
});
1013+
});
9931014
});
9941015

9951016
describe('record iframes', function (this: ISuite) {

0 commit comments

Comments
 (0)