From 2f831c5009b2894ef8750ff3abecea7ae3d54a06 Mon Sep 17 00:00:00 2001 From: John Gunther Date: Mon, 7 Oct 2024 10:53:27 -0400 Subject: [PATCH] Handle exceptions thrown from postcss when calling adaptCssForReplay --- .changeset/angry-turtles-provide.md | 5 +++++ packages/rrweb-snapshot/src/rebuild.ts | 16 +++++++++++----- packages/rrweb-snapshot/test/rebuild.test.ts | 16 +++++++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 .changeset/angry-turtles-provide.md diff --git a/.changeset/angry-turtles-provide.md b/.changeset/angry-turtles-provide.md new file mode 100644 index 00000000..94750199 --- /dev/null +++ b/.changeset/angry-turtles-provide.md @@ -0,0 +1,5 @@ +--- +"rrweb-snapshot": patch +--- + +Handle exceptions thrown from postcss when calling adaptCssForReplay diff --git a/packages/rrweb-snapshot/src/rebuild.ts b/packages/rrweb-snapshot/src/rebuild.ts index 56f6c4cf..a9dc907a 100644 --- a/packages/rrweb-snapshot/src/rebuild.ts +++ b/packages/rrweb-snapshot/src/rebuild.ts @@ -62,11 +62,17 @@ export function adaptCssForReplay(cssText: string, cache: BuildCache): string { const cachedStyle = cache?.stylesWithHoverClass.get(cssText); if (cachedStyle) return cachedStyle; - const ast: { css: string } = postcss([ - mediaSelectorPlugin, - pseudoClassPlugin, - ]).process(cssText); - const result = ast.css; + let result = cssText; + try { + const ast: { css: string } = postcss([ + mediaSelectorPlugin, + pseudoClassPlugin, + ]).process(cssText); + result = ast.css; + } catch (error) { + console.warn('Failed to adapt css for replay', error); + } + cache?.stylesWithHoverClass.set(cssText, result); return result; } diff --git a/packages/rrweb-snapshot/test/rebuild.test.ts b/packages/rrweb-snapshot/test/rebuild.test.ts index 490b515f..b78c23ec 100644 --- a/packages/rrweb-snapshot/test/rebuild.test.ts +++ b/packages/rrweb-snapshot/test/rebuild.test.ts @@ -3,7 +3,7 @@ */ import * as fs from 'fs'; import * as path from 'path'; -import { beforeEach, describe, expect as _expect, it } from 'vitest'; +import { beforeEach, describe, expect as _expect, it, vi } from 'vitest'; import { adaptCssForReplay, buildNodeWithSN, @@ -11,6 +11,7 @@ import { } from '../src/rebuild'; import { NodeType } from '../src/types'; import { createMirror, Mirror } from '../src/utils'; +import postcss from 'postcss'; const expect = _expect as unknown as { (actual: T): { @@ -248,4 +249,17 @@ ul li.specified c.\\:hover img { should_not_modify, ); }); + + it('handles exceptions from postcss when calling adaptCssForReplay', () => { + const consoleWarnSpy = vi + .spyOn(console, 'warn') + .mockImplementation(() => {}); + // trigger CssSyntaxError by passing invalid css + const cssText = 'a{'; + adaptCssForReplay(cssText, cache); + expect(consoleWarnSpy).toHaveBeenLastCalledWith( + 'Failed to adapt css for replay', + expect.any(Error), + ); + }); });