Async error handler: dispatch Eval_error to VM handler_stack in resume_vm
When an error occurs during resumed VM execution (after perform/hs-wait), resume_vm now checks the VM's handler_stack. If a handler exists (from a compiled guard form's OP_PUSH_HANDLER), it unwinds frames and jumps to the catch block — exactly like OP_RAISE. This enables try/catch across async perform/resume boundaries. The guard form compiles to OP_PUSH_HANDLER which lives on the vm struct and survives across setTimeout-based async resume. Previously, errors during resume escaped to the JS console as unhandled exceptions. Also restored guard in the test runner (was cek-try which doesn't survive async) and restored error-throwing assertions in run-action. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,16 +55,12 @@
|
||||
(= type :click)
|
||||
(let
|
||||
((el (host-call doc "querySelector" (nth action 1))))
|
||||
(when
|
||||
(nil? el)
|
||||
(error (str "Not found: " (nth action 1))))
|
||||
(when (nil? el) (error (str "Not found: " (nth action 1))))
|
||||
(host-call el "click"))
|
||||
(= type :fill)
|
||||
(let
|
||||
((el (host-call doc "querySelector" (nth action 1))))
|
||||
(when
|
||||
(nil? el)
|
||||
(error (str "Not found: " (nth action 1))))
|
||||
(when (nil? el) (error (str "Not found: " (nth action 1))))
|
||||
(host-call el "focus")
|
||||
(dom-set-prop el "value" (nth action 2))
|
||||
(dom-dispatch el "input" nil)
|
||||
@@ -74,22 +70,14 @@
|
||||
(= type :assert-text)
|
||||
(let
|
||||
((el (host-call doc "querySelector" (nth action 1))))
|
||||
(when
|
||||
(nil? el)
|
||||
(error (str "Not found: " (nth action 1))))
|
||||
(when (nil? el) (error (str "Not found: " (nth action 1))))
|
||||
(let
|
||||
((txt (host-get el "textContent"))
|
||||
((txt (dom-text-content el))
|
||||
(kw (nth action 2))
|
||||
(expected (nth action 3)))
|
||||
(when
|
||||
(and (= kw :contains) (not (contains? txt expected)))
|
||||
(error
|
||||
(str
|
||||
"Expected '"
|
||||
expected
|
||||
"' in '"
|
||||
(slice txt 0 60)
|
||||
"'")))
|
||||
(error (str "Expected '" expected "' in '" (slice txt 0 60) "'")))
|
||||
(when
|
||||
(and (= kw :not-contains) (contains? txt expected))
|
||||
(error (str "Unexpected '" expected "'")))))
|
||||
@@ -102,7 +90,8 @@
|
||||
(expected (nth action 3)))
|
||||
(when
|
||||
(and (= kw :gte) (< count expected))
|
||||
(error (str "Expected >=" expected " got " count)))))
|
||||
(str "Expected >=" expected " got " count)
|
||||
nil)))
|
||||
true
|
||||
nil))))
|
||||
(run-all
|
||||
@@ -119,13 +108,27 @@
|
||||
(console-log (str "[test] === " name " ==="))
|
||||
(reset! current (str "Running: " name))
|
||||
(reset! results (assoc (deref results) name "running"))
|
||||
(console-log "[test] calling reload-frame")
|
||||
(console-log "[test] reload-frame")
|
||||
(reload-frame)
|
||||
(console-log "[test] reload-frame done, running actions")
|
||||
(let
|
||||
((test-ok (cek-try (fn () (let ((actions (get test :actions))) (when (not (empty? actions)) (let ((first-sel (nth (first actions) 1))) (when (string? first-sel) (console-log (str "[test] wait-for-el: " first-sel)) (let ((found (wait-for-el first-sel 15))) (when (nil? found) (error (str "Timeout waiting for: " first-sel))) (console-log (str "[test] found element: " first-sel)))))) (for-each run-action actions)) (console-log (str "[test] actions done for " name)) true) (fn (e) (do (reset! results (assoc (deref results) name "fail")) (console-log (str "[test] FAIL " name ": " e)) false)))))
|
||||
(when
|
||||
test-ok
|
||||
(console-log "[test] running actions")
|
||||
(guard
|
||||
(e
|
||||
(true
|
||||
(reset! results (assoc (deref results) name "fail"))
|
||||
(console-log (str "[test] FAIL " name ": " e))))
|
||||
(let
|
||||
((actions (get test :actions)))
|
||||
(when
|
||||
(not (empty? actions))
|
||||
(let
|
||||
((first-sel (nth (first actions) 1)))
|
||||
(when
|
||||
(string? first-sel)
|
||||
(console-log (str "[test] wait-for: " first-sel))
|
||||
(let ((found (wait-for-el first-sel 15)))
|
||||
(when (nil? found)
|
||||
(error (str "Timeout waiting for: " first-sel)))))))
|
||||
(for-each run-action actions)
|
||||
(reset! results (assoc (deref results) name "pass"))
|
||||
(console-log (str "[test] PASS " name))))))
|
||||
tests)
|
||||
|
||||
Reference in New Issue
Block a user