From 042553c62206fead2a944988b81c100fe7a776ca Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Thu, 12 Oct 2023 14:20:24 -0400 Subject: [PATCH] fix(replay): Fix potential broken CSS in styled-components NOTE: This requires a bump to rrweb library 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 suppresses 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. https://github.com/getsentry/rrweb/pull/111 introduces a change the adds metadata to exceptions that occur when calling `insertRule`, and this PR will re-throw those exceptions that will then bubble up to `styled-components`. Fixes https://github.com/getsentry/sentry-javascript/issues/9170 --- packages/replay/src/integration.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts index 753fd62d5660..6cecc105d6eb 100644 --- a/packages/replay/src/integration.ts +++ b/packages/replay/src/integration.ts @@ -145,10 +145,14 @@ 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, __source__?: string}) => { try { - // @ts-expect-error Set this so that replay SDK can ignore errors originating from rrweb err.__rrweb__ = true; + + // Re-throw as styled-components relies on thrown exception when CSS rule fails to be inserted. + if (err.__source__ === 'CSSStyleSheet.insertRule') { + throw err; + } } catch { // avoid any potential hazards here }