From bb06fbbded9d81988f2c967b7eb0d779fad864f6 Mon Sep 17 00:00:00 2001 From: yashrao2607 <140533789+yashrao2607@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:09:14 +0530 Subject: [PATCH 1/2] fix: bind console-record's wrapped methods to the logger, not undefined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wrapped console method was an arrow function, so `original.apply(this, args)` never used the logger as `this` — arrow functions ignore the call-site receiver entirely and use the enclosing (non-method) call's `this`, which is undefined in this module's strict mode. Native console implementations can throw "Illegal invocation" when called with the wrong receiver, which is what crashed the reported Chrome extension content script. Bind explicitly to `_logger` instead, in both the normal call path and the internal-error fallback that has the same issue. Fixes #1772 --- .../rrweb-plugin-console-record/src/index.ts | 10 ++++- .../test/this-binding.test.ts | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 packages/plugins/rrweb-plugin-console-record/test/this-binding.test.ts diff --git a/packages/plugins/rrweb-plugin-console-record/src/index.ts b/packages/plugins/rrweb-plugin-console-record/src/index.ts index 986d7115a6..485401b888 100644 --- a/packages/plugins/rrweb-plugin-console-record/src/index.ts +++ b/packages/plugins/rrweb-plugin-console-record/src/index.ts @@ -188,7 +188,12 @@ function initLogObserver( level, (original: (...args: Array) => void) => { return (...args: Array) => { - original.apply(this, args); + // `this` here is not the logger (this arrow fn's lexical `this` is + // whatever `replace` was called with, not the console instance). + // Native console methods can throw "Illegal invocation" when + // called with the wrong receiver (observed in extension content + // scripts), so bind explicitly to `_logger`. + original.apply(_logger, args); if (level === 'assert' && !!args[0]) { // assert does not log if the first argument evaluates to true @@ -230,7 +235,8 @@ function initLogObserver( }); } } catch (error) { - original('rrweb logger error:', error, ...args); + // same `this`-binding requirement as above + original.apply(_logger, ['rrweb logger error:', error, ...args]); } finally { inStack = false; } diff --git a/packages/plugins/rrweb-plugin-console-record/test/this-binding.test.ts b/packages/plugins/rrweb-plugin-console-record/test/this-binding.test.ts new file mode 100644 index 0000000000..5a4864f7ec --- /dev/null +++ b/packages/plugins/rrweb-plugin-console-record/test/this-binding.test.ts @@ -0,0 +1,39 @@ +/** + * @vitest-environment jsdom + */ +import { describe, it, expect } from 'vitest'; +import { getRecordConsolePlugin } from '../src'; +import type { IWindow } from '@rrweb/types'; + +describe('rrweb-plugin-console-record this-binding', () => { + it('invokes the original console method with the logger as `this`', () => { + // Native console implementations in some contexts (observed in Chrome + // extension content scripts) throw "Illegal invocation" if the method + // is applied with an incorrect receiver. Simulate that here: if the + // wrapper ever calls through with the wrong `this`, this logger throws. + let capturedThis: unknown; + const fakeLogger = { + log(...args: unknown[]) { + capturedThis = this; + }, + }; + + const plugin = getRecordConsolePlugin({ + level: ['log'], + logger: fakeLogger, + }); + + const stop = plugin.observer( + () => { + // + }, + window as unknown as IWindow, + plugin.options, + ); + + fakeLogger.log('hello'); + + expect(capturedThis).toBe(fakeLogger); + stop(); + }); +}); From 45c77df9958acac94ea8d96fbd6ac207d08a9fb4 Mon Sep 17 00:00:00 2001 From: yashrao2607 <140533789+yashrao2607@users.noreply.github.com> Date: Sat, 18 Jul 2026 14:33:10 +0530 Subject: [PATCH 2/2] chore: add changeset Co-Authored-By: Claude Sonnet 5 --- .changeset/bright-cities-taste.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/bright-cities-taste.md diff --git a/.changeset/bright-cities-taste.md b/.changeset/bright-cities-taste.md new file mode 100644 index 0000000000..43aaf3990a --- /dev/null +++ b/.changeset/bright-cities-taste.md @@ -0,0 +1,5 @@ +--- +"@rrweb/rrweb-plugin-console-record": patch +--- + +Fix wrapped console methods being called with the wrong `this`, which could throw "Illegal invocation" in strict contexts such as extension content scripts