core: Phase 4 — move ex-data/ex-message/ex-cause to the overlay

The ex-info value exposes :jolt/type/:message/:data/:cause via get (it's the
caught value too), so the accessors are pure over get — no host surface. The
constructor (ex-info) stays in Janet since it wires into throw. A thrown
non-ex-info arrives wrapped as {:jolt/type :jolt/exception :value v}; the
overlay unwraps that, matching the old Janet helper. ex-cause now unwraps and
returns nil (not false) on non-ex values, matching Clojure. Added non-ex-info
and string regression cases.
This commit is contained in:
Yogthos 2026-06-07 20:17:03 -04:00
parent fcdf0ff535
commit 7f68a5872c
3 changed files with 23 additions and 13 deletions

View file

@ -236,3 +236,20 @@
(map? coll) (reduce (fn [acc k] (f acc k (get coll k))) init (keys coll))
(nil? coll) init
:else (throw (str "reduce-kv not supported on: " coll))))
;; ex-info accessors. The Janet constructor (ex-info) stays — it builds the tagged
;; value and wires into throw — but the value exposes :jolt/type/:message/:data/
;; :cause via get, so the accessors are pure over get. A thrown non-ex-info arrives
;; wrapped as {:jolt/type :jolt/exception :value v}; unwrap that first.
(defn- ex-info-val? [x] (= (get x :jolt/type) :jolt/ex-info))
(defn- ex-unwrap [e]
(if (= (get e :jolt/type) :jolt/exception) (get e :value) e))
(defn ex-data [e]
(let [e (ex-unwrap e)] (if (ex-info-val? e) (get e :data) nil)))
(defn ex-message [e]
(let [e (ex-unwrap e)]
(cond (ex-info-val? e) (get e :message)
(string? e) e
:else nil)))
(defn ex-cause [e]
(let [e (ex-unwrap e)] (if (ex-info-val? e) (get e :cause) nil)))