errors: user-readable messages and stack traces (jolt-2o7 rounds 1+2)
Before: (+ 1 "a") printed 'could not find method :+ for 1 or :r+ for "a"'
followed by three janet frames pointing at jolt internals. After:
Error: Cannot add 1 and "a" — + expects numbers
at app.deep/level3
Round 1 — compiled fns carry their Clojure identity:
- The analyzer's recur target (which doubles as the compiled janet fn's
name) is now ns/fn-name (_r$app.deep/level3--N), so janet stack traces
name the user's fns; defn passes the self-name through to fn.
- eval-toplevel re-raises with propagate instead of protect+error — the
failing fiber's stack was being discarded, which is why every trace began
at eval-toplevel.
- require/maybe-require-ns route loaded namespaces through the loader's
compile-or-interpret eval-toplevel via a ctx hook (the evaluator can't
import the loader). Previously REQUIRED namespaces always ran interpreted:
slower, and their fns were anonymous in traces.
Round 2 — report-error presents for users (rephrase-inspired):
- The full trace text is stashed at the innermost eval-toplevel boundary
(janet's debug/stacktrace walks the fiber propagation chain; debug/stack
cannot), then filtered: _r$ frames demangled to ns/fn-name, jolt-internal
and [eval] frames dropped. JOLT_DEBUG=1 restores the raw janet trace.
- Message rewrites: janet arithmetic dispatch -> 'Cannot add X and Y — +
expects numbers'; compiled arity -> Clojure's 'Wrong number of args (N)
passed to: ns/fn'; nil-call gets an undefined-symbol hint (round 3 will
fix resolution properly).
6 cli-test rows assert the exact user-visible output. Gate green, suite
4718 steady, bench within noise.
This commit is contained in:
parent
a40c715ade
commit
e0442f84e4
7 changed files with 162 additions and 12 deletions
|
|
@ -7,6 +7,12 @@
|
|||
(os/proc-wait p)
|
||||
(string (or out "")))
|
||||
|
||||
(defn- run-err [& args]
|
||||
(def p (os/spawn ["janet" "src/jolt/main.janet" ;args] :p {:out :pipe :err :pipe}))
|
||||
(def err (:read (p :err) :all))
|
||||
(os/proc-wait p)
|
||||
(string (or err "")))
|
||||
|
||||
(var fails 0)
|
||||
(defn check [label got pred]
|
||||
(if (pred got) (print " ok " label)
|
||||
|
|
@ -34,3 +40,28 @@
|
|||
(if (> fails 0)
|
||||
(error (string "cli-test: " fails " failing check(s)"))
|
||||
(print "\nAll CLI tests passed!"))
|
||||
|
||||
# --- user-facing error output (jolt-2o7 rounds 1+2) --------------------------
|
||||
# Messages are Clojure-shaped; traces show the USER'S fns (compiled fn names
|
||||
# carry ns/fn-name, demangled by report-error) and never jolt internals.
|
||||
(check "arith error message rewritten"
|
||||
(run-err "-e" `(+ 1 "a")`)
|
||||
(has `Cannot add 1 and "a"`))
|
||||
(check "arity error names the fn"
|
||||
(run-err "-e" "(defn afn [x] x) (afn 1 2)")
|
||||
(has "Wrong number of args (2) passed to: user/afn"))
|
||||
(check "nil-call hints at undefined symbol"
|
||||
(run-err "-e" "(undefined-fn 1)")
|
||||
(has "undefined (misspelled?) symbol"))
|
||||
(check "trace shows the user's call chain"
|
||||
(run-err "-e" "(defn inner [x] (let [r (+ x :k)] r)) (defn outer [x] (let [v (inner x)] v)) (outer 1)")
|
||||
(fn [s] (and (string/find "at user/inner" s) (string/find "at user/outer" s))))
|
||||
(check "no jolt-internal frames in user errors"
|
||||
(run-err "-e" `(+ 1 "a")`)
|
||||
(fn [s] (nil? (string/find "src/jolt/" s))))
|
||||
(check "JOLT_DEBUG restores the raw trace"
|
||||
(do (os/setenv "JOLT_DEBUG" "1")
|
||||
(def r (run-err "-e" `(+ 1 "a")`))
|
||||
(os/setenv "JOLT_DEBUG" nil)
|
||||
r)
|
||||
(has "could not find method"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue