Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by
When a macro fails a spec check at the repl, the message printed includes the (often large) ex-data map generated by spec explain:

Clojure 1.9.0-RC1
user=> (let [x] 5)
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr]
predicate: any?,  Insufficient input
 #:clojure.spec.alpha{:problems [{:path [:args :bindings :init-expr], :reason "Insufficient input",
:pred clojure.core/any?, :val (), :via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings], :in [0]}], :spec
#object[clojure.spec.alpha$regex_spec_impl$reify__1188 0x3f9270ed
"clojure.spec.alpha$regex_spec_impl$reify__1188@3f9270ed"], :value ([x] 5), :args ([x] 5)},

As I understand it, checkSpecs in Compiler.java calls macroexpand-check from spec. For failures, macroexpand-check throws an ExceptionInfo with the explain data in the data map. checkSpecs catches this and throws a new CompilerException, passing the ExceptionInfo as the cause. The CompilerException constructor calls toString on the cause, which for ExceptionInfo generates a string with both the message and the data map.

Possibly, you could add a new overload of the CompilerException constructor, which specifies both an explicit message and a cause (using the message in a call to errorMsg). Then checkSpecs could use this overload, passing ExceptionInfo.getMessage and avoiding printing of the data map.

I've marked this as major, because I think the data map dumps have the potential to be intimidating to newcomers.

2 Answers

0 votes

Comment made by: alexmiller

There are multiple contributors here to the messiness of the resulting message and I don't agree with the suggested solution. CompilerExceptions are designed to be wrappers (with location info) that can be unrolled to find the cause exception, so to some degree the repl catch handler bears some of the blame here - it should be doing more to unwrap and report. And it could even be doing more for specifically for spec errors if we had a marker that identified them. Also, I think the macro check should not be including the explain data string.

0 votes
Reference: https://clojure.atlassian.net/browse/CLJ-2272 (reported by glchapman)