From 5447282934cc895d9ba9954efc7a0bde74cdfb6d Mon Sep 17 00:00:00 2001 From: alexander-akait Date: Fri, 28 Mar 2025 15:50:03 +0300 Subject: [PATCH] fix: do not crush when error is null for runtime errors --- client-src/overlay.js | 8 +++++- .../{clients => }/ReactErrorBoundary.test.js | 25 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) rename test/client/{clients => }/ReactErrorBoundary.test.js (91%) diff --git a/client-src/overlay.js b/client-src/overlay.js index 6f4c05722a..c4ceb97e5b 100644 --- a/client-src/overlay.js +++ b/client-src/overlay.js @@ -664,10 +664,16 @@ const createOverlay = (options) => { if (!error && !message) { return; } + // if error stack indicates a React error boundary caught the error, do not show overlay. - if (error.stack && error.stack.includes("invokeGuardedCallbackDev")) { + if ( + error && + error.stack && + error.stack.includes("invokeGuardedCallbackDev") + ) { return; } + handleError(error, message); }); diff --git a/test/client/clients/ReactErrorBoundary.test.js b/test/client/ReactErrorBoundary.test.js similarity index 91% rename from test/client/clients/ReactErrorBoundary.test.js rename to test/client/ReactErrorBoundary.test.js index 647cae1ff5..03f27f0efb 100644 --- a/test/client/clients/ReactErrorBoundary.test.js +++ b/test/client/ReactErrorBoundary.test.js @@ -4,7 +4,7 @@ "use strict"; -const { createOverlay } = require("../../../client-src/overlay"); +const { createOverlay } = require("../../client-src/overlay"); describe("createOverlay", () => { const originalDocument = global.document; @@ -108,6 +108,29 @@ describe("createOverlay", () => { showOverlayMock.mockRestore(); }); + it("should show overlay for normal uncaught errors (when null is thrown)", () => { + const options = { trustedTypesPolicyName: null, catchRuntimeError: true }; + const overlay = createOverlay(options); + const showOverlayMock = jest.spyOn(overlay, "send"); + + const errorEvent = new ErrorEvent("error", { + error: null, + message: "error", + }); + window.dispatchEvent(errorEvent); + + expect(showOverlayMock).toHaveBeenCalledWith({ + type: "RUNTIME_ERROR", + messages: [ + { + message: "error", + stack: expect.anything(), + }, + ], + }); + showOverlayMock.mockRestore(); + }); + it("should show overlay for normal uncaught errors when catchRuntimeError is a function that return true", () => { const options = { trustedTypesPolicyName: null,