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:
@@ -617,7 +617,25 @@ function record<T = eventWithTime>(
|
||||
);
|
||||
}
|
||||
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();
|
||||
recording = false;
|
||||
unregisterErrorHandler();
|
||||
|
||||
@@ -990,6 +990,27 @@ describe('record', function (this: ISuite) {
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user