fix(rrdom): Ignore invalid DOM attributes when diffing (#1561)
* fix(rrdom): Ignore invalid DOM attributes when diffing (#213)
We encountered an issue where replays with invalid attributes (e.g.
`@click`) would break rendering the replay after seeking. The exception
bubbles up to
[here](62093d4385/packages/rrweb/src/replay/index.ts (L270-L279)),
which means the replay will continue to play, but the replay mirror will
be incomplete.
Closes https://github.com/getsentry/team-replay/issues/458
* add changeset
This commit is contained in:
5
.changeset/chilled-penguins-sin.md
Normal file
5
.changeset/chilled-penguins-sin.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"rrdom": patch
|
||||
---
|
||||
|
||||
Ignore invalid DOM attributes when diffing
|
||||
@@ -354,7 +354,16 @@ function diffProps(
|
||||
}
|
||||
};
|
||||
} else if (newTree.tagName === 'IFRAME' && name === 'srcdoc') continue;
|
||||
else oldTree.setAttribute(name, newValue);
|
||||
else {
|
||||
try {
|
||||
oldTree.setAttribute(name, newValue);
|
||||
} catch (err) {
|
||||
// We want to continue diffing so we quietly catch
|
||||
// this exception. Otherwise, this can throw and bubble up to
|
||||
// the `ReplayerEvents.Flush` listener and break rendering
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const { name } of Array.from(oldAttributes))
|
||||
|
||||
@@ -335,6 +335,32 @@ describe('diff algorithm for rrdom', () => {
|
||||
expect((node as Node as HTMLElement).className).toBe('node');
|
||||
});
|
||||
|
||||
it('ignores invalid attributes', () => {
|
||||
const tagName = 'DIV';
|
||||
const node = document.createElement(tagName);
|
||||
const sn = Object.assign({}, elementSn, {
|
||||
attributes: { '@click': 'foo' },
|
||||
tagName,
|
||||
});
|
||||
mirror.add(node, sn);
|
||||
|
||||
const rrDocument = new RRDocument();
|
||||
const rrNode = rrDocument.createElement(tagName);
|
||||
const sn2 = Object.assign({}, elementSn, {
|
||||
attributes: { '@click': 'foo' },
|
||||
tagName,
|
||||
});
|
||||
rrDocument.mirror.add(rrNode, sn2);
|
||||
|
||||
rrNode.attributes = { id: 'node1', class: 'node', '@click': 'foo' };
|
||||
diff(node, rrNode, replayer);
|
||||
expect((node as Node as HTMLElement).id).toBe('node1');
|
||||
expect((node as Node as HTMLElement).className).toBe('node');
|
||||
expect('@click' in (node as Node as HTMLElement)).toBe(false);
|
||||
expect(warn).toHaveBeenCalledTimes(1);
|
||||
warn.mockClear();
|
||||
});
|
||||
|
||||
it('can update exist properties', () => {
|
||||
const tagName = 'DIV';
|
||||
const node = document.createElement(tagName);
|
||||
|
||||
Reference in New Issue
Block a user