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 <eoghan@getthere.ie> * remove settimeout --------- Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
This commit is contained in:
5
.changeset/nervous-actors-jam.md
Normal file
5
.changeset/nervous-actors-jam.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"rrweb": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: rrweb recorder may throw error when stopping recording after an iframe becomes cross-origin
|
||||||
@@ -617,7 +617,25 @@ function record<T = eventWithTime>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
handlers.forEach((h) => h());
|
handlers.forEach((handler) => {
|
||||||
|
try {
|
||||||
|
handler();
|
||||||
|
} catch (error) {
|
||||||
|
const msg = String(error).toLowerCase();
|
||||||
|
/**
|
||||||
|
* https://github.com/rrweb-io/rrweb/pull/1695
|
||||||
|
* This error can occur in a known scenario:
|
||||||
|
* If an iframe is initially same-origin and observed, but later its
|
||||||
|
location is changed in an opaque way to a cross-origin URL (perhaps within the iframe via its `document.location` or a redirect)
|
||||||
|
* attempting to execute the handler in the stop record function will
|
||||||
|
throw a "cannot access cross-origin frame" error.
|
||||||
|
* This error is expected and can be safely ignored.
|
||||||
|
*/
|
||||||
|
if (!msg.includes('cross-origin')) {
|
||||||
|
console.warn(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
processedNodeManager.destroy();
|
processedNodeManager.destroy();
|
||||||
recording = false;
|
recording = false;
|
||||||
unregisterErrorHandler();
|
unregisterErrorHandler();
|
||||||
|
|||||||
@@ -990,6 +990,27 @@ describe('record', function (this: ISuite) {
|
|||||||
|
|
||||||
await assertSnapshot(ctx.events);
|
await assertSnapshot(ctx.events);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not throw error when stopping recording after iframe becomes cross-origin', async () => {
|
||||||
|
await ctx.page.evaluate(async () => {
|
||||||
|
const { record } = (window as unknown as IWindow).rrweb;
|
||||||
|
const stopRecord = record({
|
||||||
|
emit: (window as unknown as IWindow).emit,
|
||||||
|
});
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
(window as any).stopRecord = stopRecord;
|
||||||
|
(window as any).iframe = iframe;
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
});
|
||||||
|
await waitForRAF(ctx.page);
|
||||||
|
await ctx.page.evaluate(async () => {
|
||||||
|
(window as any).iframe.src = 'https://www.example.com'; // Change the same origin iframe to a cross origin iframe after it's recorded
|
||||||
|
});
|
||||||
|
await waitForRAF(ctx.page);
|
||||||
|
await ctx.page.evaluate(() => {
|
||||||
|
(window as any).stopRecord?.();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('record iframes', function (this: ISuite) {
|
describe('record iframes', function (this: ISuite) {
|
||||||
|
|||||||
Reference in New Issue
Block a user