Reject a malformed catch clause with a clean error in both modes
jolt's catch is (catch class binding body*); the binding (3rd element) must be a symbol. Neither the analyzer nor the interpreter validated it, so a non-symbol binding crashed with an internal Janet error (expected integer key for array...) and, in the interpreter, a malformed clause whose body never threw was silently swallowed (returned the try value). Clojure rejects a non-class/non-symbol catch clause; match that with an up-front error in analyze-try and eval-try. Surfaced building the Chez try/throw emit. Regression rows in exceptions-spec (runs x3 modes) plus a unit test asserting the clean message in interpret and compile. jolt-kg6p.
This commit is contained in:
parent
ffa122440a
commit
d35783bf1b
4 changed files with 67 additions and 1 deletions
|
|
@ -15,7 +15,12 @@
|
|||
["finally runs on throw" "9"
|
||||
"(let [a (atom 0)] (try (throw (ex-info \"x\" {})) (catch :default e nil) (finally (reset! a 9))) @a)"]
|
||||
["catch value of body" "5"
|
||||
"(try (+ 2 3) (catch :default e 0))"])
|
||||
"(try (+ 2 3) (catch :default e 0))"]
|
||||
# a malformed catch clause (binding not a symbol, or clause too short) is a
|
||||
# clean error, not a silent nil or an internal crash (jolt-kg6p).
|
||||
["malformed catch: non-symbol binding" :throws "(try 1 (catch e (* e 10)))"]
|
||||
["malformed catch: literal binding" :throws "(try 1 (catch e 5))"]
|
||||
["malformed catch: too short" :throws "(try 1 (catch Exception))"])
|
||||
|
||||
(defspec "exceptions / assert"
|
||||
["assert true -> ok" ":ok" "(do (assert true) :ok)"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue