Skip to content

Commit

Permalink
fix(replay): Fix potential broken CSS in styled-components (#9234)
Browse files Browse the repository at this point in the history
Fixes an issue where the Replay integration can potentially break
applications that use `styled-components`. `styled-components` [relies
on an exception being
throw](https://github.com/styled-components/styled-components/blob/b7b374bb1ceff1699f7035b15881bc807110199a/packages/styled-components/src/sheet/Tag.ts#L32-L40)
for CSS rules that are not supported by the browser engine. However, our
SDK suppressed any exceptions thrown from within rrweb, so
`styled-components` assumes that an unsupported rule was inserted
successfully and increases a rule index, which causes following inserted
rules to fail due to an out-of-bounds error.

This was a regression from v1 as [we were always re-throwing the
exception](https://github.com/getsentry/rrweb/blob/sentry-v1/packages/rrweb/src/sentry/callbackWrapper.ts#L17)

Fixes #9170

---------

Co-authored-by: Francesco Novy <francesco.novy@sentry.io>
  • Loading branch information
billyvg and mydea committed Oct 13, 2023
1 parent a8c8564 commit 73a808a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';
import { shouldSkipReplayTest } from '../../../utils/replayHelpers';

sentryTest('exceptions within rrweb and re-thrown and annotated', async ({ getLocalTestPath, page, browserName }) => {
if (shouldSkipReplayTest() || browserName !== 'chromium') {
sentryTest.skip();
}

const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);

expect(
await page.evaluate(() => {
try {
const s = new CSSStyleSheet();
s.insertRule('body::-ms-expand{display: none}');
s.insertRule('body {background-color: #fff;}');
return s.cssRules.length;
} catch {
return false;
}
}),
).toBe(false);

expect(
await page.evaluate(() => {
const s = new CSSStyleSheet();
s.insertRule('body {background-color: #fff;}');
return s.cssRules.length;
}),
).toBe(1);
});
10 changes: 4 additions & 6 deletions packages/replay/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,13 @@ export class Replay implements Integration {
// collect fonts, but be aware that `sentry.io` needs to be an allowed
// origin for playback
collectFonts: true,
errorHandler: (err: Error) => {
errorHandler: (err: Error & { __rrweb__?: boolean }) => {
try {
// @ts-expect-error Set this so that replay SDK can ignore errors originating from rrweb
err.__rrweb__ = true;
} catch {
// avoid any potential hazards here
} catch (error) {
// ignore errors here
// this can happen if the error is frozen or does not allow mutation for other reasons
}
// return true to suppress throwing the error inside of rrweb
return true;
},
};

Expand Down

0 comments on commit 73a808a

Please sign in to comment.