🐛 Add minor improvements on wasm-render error handling

This commit is contained in:
Andrey Antukh 2026-03-16 14:34:06 +01:00 committed by Belén Albeza
parent 0d236110e9
commit 2d5392327e
6 changed files with 44 additions and 49 deletions

View File

@ -127,24 +127,15 @@
(ex/print-throwable cause :prefix "Unexpected Error")
(flash :cause cause :type :unhandled))))
(defmethod ptk/handle-error :wasm-non-blocking
(defmethod ptk/handle-error :wasm-error
[error]
(when-let [cause (::instance error)]
(flash :cause cause)))
(defmethod ptk/handle-error :wasm-critical
[error]
(when-let [cause (::instance error)]
(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)))
(ex/print-throwable cause)
(let [code (get error :code)]
(if (or (= code :panic)
(= code :webgl-context-lost))
(st/emit! (rt/assign-exception error))
(flash :type :handled :cause cause)))))
;; We receive a explicit authentication error; If the uri is for
;; workspace, dashboard, viewer or settings, then assign the exception
@ -376,19 +367,24 @@
(let [data (ex-data cause)
type (get data :type)]
(set! last-exception cause)
(if (#{:wasm-critical :wasm-non-blocking :wasm-exception} type)
(if (= :wasm-error type)
(on-error cause)
(do
(ex/print-throwable cause :prefix "Uncaught Exception")
(ts/schedule #(flash :cause cause :type :unhandled))))))))
(ts/asap #(flash :cause cause :type :unhandled))))))))
(on-unhandled-rejection [event]
(.preventDefault ^js event)
(when-let [cause (unchecked-get event "reason")]
(when-not (is-ignorable-exception? cause)
(set! last-exception cause)
(ex/print-throwable cause :prefix "Uncaught Rejection")
(ts/schedule #(flash :cause cause :type :unhandled)))))]
(let [data (ex-data cause)
type (get data :type)]
(set! last-exception cause)
(if (= :wasm-error type)
(on-error cause)
(do
(ex/print-throwable cause :prefix "Uncaught Rejection")
(ts/asap #(flash :cause cause :type :unhandled))))))))]
(.addEventListener g/window "error" on-unhandled-error)
(.addEventListener g/window "unhandledrejection" on-unhandled-rejection)

View File

@ -15,12 +15,10 @@
[rumext.v2 :as mf]))
(mf/defc error-boundary*
{::mf/props :obj}
[{:keys [fallback children]}]
(let [fallback-wrapper
(mf/with-memo [fallback]
(mf/fnc fallback-wrapper*
{::mf/props :obj}
[{:keys [error reset-error-boundary]}]
(let [route (mf/deref refs/route)
data (errors/exception->error-data error)]

View File

@ -477,8 +477,8 @@
:service-unavailable
[:> service-unavailable*]
:wasm-exception
(case (get data :exception-type)
:wasm-error
(case (get data :code)
:webgl-context-lost
[:> webgl-context-lost*]

View File

@ -57,6 +57,7 @@
[app.render-wasm.api :as wasm.api]
[app.util.debug :as dbg]
[app.util.text-editor :as ted]
[app.util.timers :as ts]
[beicon.v2.core :as rx]
[promesa.core :as p]
[rumext.v2 :as mf]))
@ -361,9 +362,9 @@
(mf/with-effect [focus]
(when (and @canvas-init? @initialized?)
(if (empty? focus)
(wasm.api/clear-focus-mode)
(wasm.api/set-focus-mode focus))))
(ts/asap #(if (empty? focus)
(wasm.api/clear-focus-mode)
(wasm.api/set-focus-mode focus)))))
(mf/with-effect [vbox zoom]
(when (and @canvas-init? initialized?)

View File

@ -1420,11 +1420,9 @@
[event]
(dom/prevent-default event)
(reset! wasm/context-lost? true)
(log/warn :hint "WebGL context lost")
(ex/raise :type :wasm-exception
:exception-type :webgl-context-lost
:prefix "WebGL context lost"
:hint "WebGL context lost"))
(ex/raise :type :wasm-error
:code :webgl-context-lost
:hint "WASM Error: WebGL context lost"))
(defn init-canvas-context
[canvas]

View File

@ -5,11 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.render-wasm.helpers
#?(:cljs (:require-macros [app.render-wasm.helpers])))
#?(:cljs (:require-macros [app.render-wasm.helpers]))
(:require [app.common.data :as d]))
(def ^:export error-code
(def error-code
"WASM error code constants (must match render-wasm/src/error.rs and mem.rs)."
{0x01 :wasm-non-blocking 0x02 :wasm-critical})
{0x01 :non-blocking
0x02 :panic})
(defmacro call
"A helper for calling a wasm function.
@ -18,19 +20,19 @@
- :wasm-non-blocking: call app.main.errors/on-error (eventually, shows a toast and logs the error)
- :wasm-critical or unknown: throws an exception to be handled by the global error handler (eventually, shows the internal error page)"
[module name & params]
(let [fn-sym (with-meta (gensym "fn-") {:tag 'function})
e-sym (gensym "e")
code-sym (gensym "code")]
(let [fn-sym (with-meta (gensym "fn-") {:tag 'function})
cause-sym (gensym "cause")]
`(let [~fn-sym (cljs.core/unchecked-get ~module ~name)]
(try
(~fn-sym ~@params)
(catch :default ~e-sym
(let [read-code# (cljs.core/unchecked-get ~module "_read_error_code")
~code-sym (when read-code# (read-code#))
type# (or (get app.render-wasm.helpers/error-code ~code-sym) :wasm-critical)
ex# (ex-info (str "WASM error (type: " type# ")")
{:fn ~name :type type# :message (.-message ~e-sym) :error-code ~code-sym}
~e-sym)]
(if (= type# :wasm-non-blocking)
(@~'app.main.store/on-error ex#)
(throw ex#))))))))
(catch :default ~cause-sym
(let [read-code-fn# (cljs.core/unchecked-get ~module "_read_error_code")
code-num# (when read-code-fn# (read-code-fn#))
code# (get error-code code-num# :wasm-critical)
hint# (str "WASM Error (" (d/name code#) ")")
context# {:type :wasm-error
:code code#
:hint hint#
:fn ~name}
cause# (ex-info hint# context# ~cause-sym)]
(throw cause#)))))))