HS: asyncError — rejected promise triggers catch block (+1 test)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Three-part fix for hs-upstream-core/asyncError test 2/2:
1. runtime.sx hs-win-call: when an async call returns a rejected promise,
store the error value in window.__hs_async_error (side-channel) and
raise the sentinel "__hs_async_error__" so the value survives the
raise boundary intact.
2. compiler.sx catch clause: inject `(let ((var (host-hs-normalize-exc var))) ...)`
around the catch body so the sentinel gets swapped for the real error
object before user code runs. Uses let (not set!) so shadowing works
correctly for guard catch variables.
3. tests/hs-run-filtered.js:
- host-promise-state wraps JS Error objects as plain {message:...} dicts
before they cross the WASM boundary (Error.toString() was producing
"Error: boom" strings instead of accessible objects)
- host-hs-normalize-exc native retrieves the side-channel value when
the sentinel arrives in a catch variable
- host-get coercion restricted to El instances — plain JS objects with
a "value" key were being stringified to "[object Object]"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -237,7 +237,7 @@
|
||||
(let
|
||||
((compiled-body (let ((base (if (> (len event-refs) 0) (let ((bindings (map (fn (r) (let ((name (nth r 1))) (list (make-symbol name) (list (quote let) (list (list (quote _det) (list (quote host-get) (quote event) "detail"))) (list (quote if) (list (quote and) (quote _det) (list (quote not) (list (quote nil?) (list (quote host-get) (quote _det) name)))) (list (quote host-get) (quote _det) name) (list (quote host-get) (quote event) name)))))) event-refs))) (list (quote let) bindings raw-compiled)) raw-compiled))) (if elsewhere? (list (quote when) (list (quote not) (list (quote host-call) (quote me) "contains" (list (quote host-get) (quote event) "target"))) base) base))))
|
||||
(let
|
||||
((wrapped-body (if catch-info (let ((var (make-symbol (nth catch-info 0))) (catch-body (hs-to-sx (nth catch-info 1)))) (if finally-info (list (quote let) (list (list (quote __hs-exc) nil) (list (quote __hs-reraise) false)) (list (quote do) (list (quote guard) (list var (list true (list (quote guard) (list (quote __inner-exc) (list true (list (quote do) (list (quote set!) (quote __hs-exc) (quote __inner-exc)) (list (quote set!) (quote __hs-reraise) true)))) catch-body))) compiled-body) (hs-to-sx finally-info) (list (quote when) (quote __hs-reraise) (list (quote raise) (quote __hs-exc))))) (list (quote let) (list (list (quote __hs-exc) nil) (list (quote __hs-reraise) false)) (list (quote guard) (list var (list true (list (quote guard) (list (quote __inner-exc) (list true (list (quote do) (list (quote set!) (quote __hs-exc) (quote __inner-exc)) (list (quote set!) (quote __hs-reraise) true)))) catch-body))) compiled-body) (list (quote when) (quote __hs-reraise) (list (quote raise) (quote __hs-exc)))))) (if finally-info (list (quote do) compiled-body (hs-to-sx finally-info)) compiled-body))))
|
||||
((wrapped-body (if catch-info (let ((var (make-symbol (nth catch-info 0))) (catch-body (hs-to-sx (nth catch-info 1)))) (if finally-info (list (quote let) (list (list (quote __hs-exc) nil) (list (quote __hs-reraise) false)) (list (quote do) (list (quote guard) (list var (list true (list (quote let) (list (list var (list (quote host-hs-normalize-exc) var))) (list (quote guard) (list (quote __inner-exc) (list true (list (quote do) (list (quote set!) (quote __hs-exc) (quote __inner-exc)) (list (quote set!) (quote __hs-reraise) true)))) catch-body)))) compiled-body) (hs-to-sx finally-info) (list (quote when) (quote __hs-reraise) (list (quote raise) (quote __hs-exc))))) (list (quote let) (list (list (quote __hs-exc) nil) (list (quote __hs-reraise) false)) (list (quote guard) (list var (list true (list (quote let) (list (list var (list (quote host-hs-normalize-exc) var))) (list (quote guard) (list (quote __inner-exc) (list true (list (quote do) (list (quote set!) (quote __hs-exc) (quote __inner-exc)) (list (quote set!) (quote __hs-reraise) true)))) catch-body)))) compiled-body) (list (quote when) (quote __hs-reraise) (list (quote raise) (quote __hs-exc)))))) (if finally-info (list (quote do) compiled-body (hs-to-sx finally-info)) compiled-body))))
|
||||
(let
|
||||
((handler (let ((uses-the-result? (fn (expr) (cond ((= expr (quote the-result)) true) ((list? expr) (some (fn (x) (uses-the-result? x)) expr)) (true false))))) (let ((base-handler (list (quote fn) (list (quote event)) (if (uses-the-result? wrapped-body) (list (quote let) (list (list (quote the-result) nil)) wrapped-body) wrapped-body)))) (if count-filter-info (let ((mn (get count-filter-info "min")) (mx (get count-filter-info "max"))) (list (quote let) (list (list (quote __hs-count) 0)) (list (quote fn) (list (quote event)) (list (quote begin) (list (quote set!) (quote __hs-count) (list (quote +) (quote __hs-count) 1)) (list (quote when) (if (= mx -1) (list (quote >=) (quote __hs-count) mn) (list (quote and) (list (quote >=) (quote __hs-count) mn) (list (quote <=) (quote __hs-count) mx))) (nth base-handler 2)))))) base-handler)))))
|
||||
(let
|
||||
|
||||
@@ -360,7 +360,7 @@
|
||||
(when
|
||||
(not (nil? target))
|
||||
(let
|
||||
((str-val (if (list? value) (join "" (map (fn (x) (str x)) value)) (str value))))
|
||||
((str-val (if (list? value) (join "" (map (fn (x) (str x)) value)) (if (= value nil) "null" (str value)))))
|
||||
(do
|
||||
(dom-set-inner-html target str-val)
|
||||
(hs-boot-subtree! target)))))))
|
||||
@@ -2776,7 +2776,22 @@
|
||||
((fn (host-get (host-global "window") fn-name)))
|
||||
(if
|
||||
fn
|
||||
(host-call-fn fn args)
|
||||
(let
|
||||
((result (host-call-fn fn args)))
|
||||
(if
|
||||
(= (host-typeof result) "promise")
|
||||
(let
|
||||
((state (host-promise-state result)))
|
||||
(if
|
||||
(and state (= (host-get state "ok") false))
|
||||
(do
|
||||
(host-set!
|
||||
(host-global "window")
|
||||
"__hs_async_error"
|
||||
(host-get state "value"))
|
||||
(raise "__hs_async_error__"))
|
||||
(if state (host-get state "value") result)))
|
||||
result))
|
||||
(let
|
||||
((msg (str "'" fn-name "' is null")))
|
||||
(host-set! (host-global "window") "_hs_null_error" msg)
|
||||
|
||||
Reference in New Issue
Block a user