plumatic / schema

Clojure(Script) library for declarative data description and validation
Other
2.41k stars 257 forks source link

Better exceptions for recursive schemas #287

Closed wavejumper closed 8 years ago

wavejumper commented 9 years ago

Using schema 1.0.1, I have noticed ridiculously large exceptions being thrown for my recursive schemas (>40,000 lines - which crashes emacs!)

An example:

(def TestSchema
  {:a (s/eq :b)
   :b [s/Str]
   (s/optional-key :bar) [(s/recursive #'TestSchema)]
   (s/optional-key :foo) (s/recursive #'TestSchema)})

(s/validate TestSchema {:a :c})

For me returns a 3284 line exception, then stack overflows!

w01fe commented 9 years ago

What Clojure(Script) version are you using? Are you using any lein plugins such as Pretty? May be related to #277

Can you please paste the results for the above example? Here's what I see:

user> (s/validate TestSchema {:a :c})
ExceptionInfo Value does not match schema: {:a (not (= :b :c)), :b missing-required-key}  schema.core/validator/fn--9032 (core.clj:151)
user> (pst *e)
ExceptionInfo Value does not match schema: {:a (not (= :b :c)), :b missing-required-key} {:type :schema.core/error, :schema {:a (eq :b), :b [java.lang.String], #schema.core.OptionalKey{:k :bar} [(recursive (var user/TestSchema))], #schema.core.OptionalKey{:k :foo} (recursive (var user/TestSchema))}, :value {:a :c}, :error {:a (not (= :b :c)), :b missing-required-key}}
    schema.core/validator/fn--9032 (core.clj:151)
    schema.core/validate (core.clj:160)
    user/eval20560 (form-init8538199752670453457.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:6782)
    clojure.lang.Compiler.eval (Compiler.java:6745)
    clojure.core/eval (core.clj:3081)
    clojure.main/repl/read-eval-print--7099/fn--7102 (main.clj:240)
    clojure.main/repl/read-eval-print--7099 (main.clj:240)
    clojure.main/repl/fn--7108 (main.clj:258)
    clojure.main/repl (main.clj:258)
    clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn--883 (interruptible_eval.clj:43)
    clojure.core/apply (core.clj:630)
wavejumper commented 9 years ago

Clojure 1.7.0

Yeah, removing ultra from my plugins stopped s/validate from stack overflowing in the above example.

Without ultra it still returned an exception with huge exception data - which I'm OK with so long as it doesn't crash my REPL!

https://gist.github.com/wavejumper/9d87852fdf6d1c35848b

w01fe commented 8 years ago

After looking into this a bit more, I think the only possible fix on our side would be to remove the schema from the ex-data. In my opinion it has a right to be there, and the issue is with whatever editor/plugin decides to print the full ex-data (moreover, without respecting the user's print-method).