From d9487610908aea41cda4f55ee759274af998d7e9 Mon Sep 17 00:00:00 2001 From: Elena Torro Date: Mon, 9 Mar 2026 16:45:27 +0100 Subject: [PATCH] :bug: Fix WebGL context lost error to raise an exception and show the exception page --- .../playwright/ui/specs/render-wasm.spec.js | 23 +++++++++++++++++++ frontend/src/app/main/errors.cljs | 9 +++++++- frontend/src/app/main/ui/static.cljs | 8 +++++-- frontend/src/app/render_wasm/api.cljs | 4 +++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/frontend/playwright/ui/specs/render-wasm.spec.js b/frontend/playwright/ui/specs/render-wasm.spec.js index 1c336bf6a8..c764df70b1 100644 --- a/frontend/playwright/ui/specs/render-wasm.spec.js +++ b/frontend/playwright/ui/specs/render-wasm.spec.js @@ -16,6 +16,29 @@ test.skip("BUG 10867 - Crash when loading comments", async ({ page }) => { ).toBeVisible(); }); +test("BUG 13541 - Shows error page when WebGL context is lost", async ({ + page, +}) => { + const workspacePage = new WasmWorkspacePage(page); + await workspacePage.setupEmptyFile(); + await workspacePage.goToWorkspace(); + await workspacePage.waitForFirstRender(); + + // Simulate a WebGL context loss by dispatching the event on the canvas + await workspacePage.canvas.evaluate((canvas) => { + const event = new Event("webglcontextlost", { cancelable: true }); + canvas.dispatchEvent(event); + }); + + await expect( + page.getByText("Oops! The canvas context was lost"), + ).toBeVisible(); + await expect( + page.getByText("WebGL has stopped working"), + ).toBeVisible(); + await expect(page.getByText("Reload page")).toBeVisible(); +}); + test.skip("BUG 12164 - Crash when trying to fetch a missing font", async ({ page, }) => { diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 6466e414da..9968e4641a 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -127,6 +127,13 @@ (ex/print-throwable cause :prefix "WASM critical error")) (st/emit! (rt/assign-exception error))) +(defmethod ptk/handle-error :wasm-exception + [error] + (when-let [cause (::instance error)] + (let [prefix (or (:prefix error) "Exception")] + (ex/print-throwable cause :prefix prefix))) + (st/emit! (rt/assign-exception error))) + ;; We receive a explicit authentication error; If the uri is for ;; workspace, dashboard, viewer or settings, then assign the exception ;; for show the error page. Otherwise this explicitly clears all @@ -343,7 +350,7 @@ (set! last-exception cause) (let [data (ex-data cause) type (get data :type)] - (if (#{:wasm-critical :wasm-non-blocking} type) + (if (#{:wasm-critical :wasm-non-blocking :wasm-exception} type) (on-error cause) (when-not (is-ignorable-exception? cause) (ex/print-throwable cause :prefix "Uncaught Exception") diff --git a/frontend/src/app/main/ui/static.cljs b/frontend/src/app/main/ui/static.cljs index 7f0020ccd3..e589322368 100644 --- a/frontend/src/app/main/ui/static.cljs +++ b/frontend/src/app/main/ui/static.cljs @@ -478,8 +478,12 @@ :service-unavailable [:> service-unavailable*] - :webgl-context-lost - [:> webgl-context-lost*] + :wasm-exception + (case (get data :exception-type) + :webgl-context-lost + [:> webgl-context-lost*] + + [:> internal-error* props]) [:> internal-error* props]))) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 8f037e2f9d..82fb16ebaa 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -1421,7 +1421,9 @@ (dom/prevent-default event) (reset! wasm/context-lost? true) (log/warn :hint "WebGL context lost") - (ex/raise :type :webgl-context-lost + (ex/raise :type :wasm-exception + :exception-type :webgl-context-lost + :prefix "WebGL context lost" :hint "WebGL context lost")) (defn init-canvas-context