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,