Comments (7)
more info:
This seems to be Clojure problem. Not sure if there is already a ticket for it though. Doing the same commands as above you still get 2 different errors in the repl
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.lang.Compiler$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__2436 0x5b77ed8c "clojure.spec.alpha$regex_spec_impl$reify__2436@5b77ed8c"], :value ([a 2 b]), :args ([a 2 b])}, compiling:(/Users/Camilo/Proyectos/kamal/src/hiposfer/kamal/dev.clj:55:1)
from expound.
@carocad Thanks for reporting this. Yes, you're correct: this is an issue with the way Clojure prints out data when it sees an exception (and the information attached to an exception when instrumentation fails).
I agree, it's very noisy and repetitive. Unfortunately, the expound printer can't control this directly. I'm not sure of the best fix here, but I seem to recall that it's possible to configure a REPL to install a different exception handler. I haven't tried this myself though.
If you figure out a workaround in your environment, please let me know and I may add it to the docs! I'll also look into this myself at some point.
from expound.
@bhb after some comments in the slack channel it seems that this is not a Clojure problem but a Cursive/expound one.
Clojure returns a single compiler$compilerException
but that exception contains a compiler exception and an ex-info
(ExceptionInfo
). I guess that both Cursive and expound are just printing every exception that they get their hands into thus causing a double printing.
You can replicate this by doing
(let [1 2])
*e ;; -> will print the real last exception.
for the record I am putting here the result of the above command just in case we get different results 😆
#error{:cause "Call to clojure.core/let did not conform to spec:
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/seq-binding-form at: [:args :bindings :binding :seq] predicate: vector?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map] predicate: coll?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-special-binding at: [:args :bindings :binding :map] predicate: map?
",
:data #:clojure.spec.alpha{:problems ({:path [:args :bindings :binding :sym],
:pred clojure.core/simple-symbol?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/local-name],
:in [0 0]}
{:path [:args :bindings :binding :seq],
:pred clojure.core/vector?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/seq-binding-form],
:in [0 0]}
{:path [:args :bindings :binding :map],
:pred clojure.core/coll?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/map-binding-form
:clojure.core.specs.alpha/map-bindings],
:in [0 0]}
{:path [:args :bindings :binding :map],
:pred map?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/map-binding-form
:clojure.core.specs.alpha/map-special-binding],
:in [0 0]}),
:spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436
0x122eca20
"clojure.spec.alpha$regex_spec_impl$reify__2436@122eca20"],
:value ([1 2]),
:args ([1 2])},
:via [{:type clojure.lang.Compiler$CompilerException,
:message "clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/seq-binding-form at: [:args :bindings :binding :seq] predicate: vector?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map] predicate: coll?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-special-binding at: [:args :bindings :binding :map] predicate: map?
#:clojure.spec.alpha{:problems ({:path [:args :bindings :binding :sym], :pred clojure.core/simple-symbol?, :val 1, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/local-name], :in [0 0]} {:path [:args :bindings :binding :seq], :pred clojure.core/vector?, :val 1, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/seq-binding-form], :in [0 0]} {:path [:args :bindings :binding :map], :pred clojure.core/coll?, :val 1, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings], :in [0 0]} {:path [:args :bindings :binding :map], :pred map?, :val 1, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-special-binding], :in [0 0]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x122eca20 \"clojure.spec.alpha$regex_spec_impl$reify__2436@122eca20\"], :value ([1 2]), :args ([1 2])}, compiling:(/Users/Camilo/Proyectos/kamal/src/hiposfer/kamal/dev.clj:56:1)",
:at [clojure.lang.Compiler checkSpecs "Compiler.java" 6891]}
{:type clojure.lang.ExceptionInfo,
:message "Call to clojure.core/let did not conform to spec:
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/seq-binding-form at: [:args :bindings :binding :seq] predicate: vector?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map] predicate: coll?
In: [0 0] val: 1 fails spec: :clojure.core.specs.alpha/map-special-binding at: [:args :bindings :binding :map] predicate: map?
",
:data #:clojure.spec.alpha{:problems ({:path [:args :bindings :binding :sym],
:pred clojure.core/simple-symbol?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/local-name],
:in [0 0]}
{:path [:args :bindings :binding :seq],
:pred clojure.core/vector?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/seq-binding-form],
:in [0 0]}
{:path [:args :bindings :binding :map],
:pred clojure.core/coll?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/map-binding-form
:clojure.core.specs.alpha/map-bindings],
:in [0 0]}
{:path [:args :bindings :binding :map],
:pred map?,
:val 1,
:via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/binding
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/map-binding-form
:clojure.core.specs.alpha/map-special-binding],
:in [0 0]}),
:spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436
0x122eca20
"clojure.spec.alpha$regex_spec_impl$reify__2436@122eca20"],
:value ([1 2]),
:args ([1 2])},
:at [clojure.core$ex_info invokeStatic "core.clj" 4739]}],
:trace [[clojure.core$ex_info invokeStatic "core.clj" 4739]
[clojure.core$ex_info invoke "core.clj" 4739]
[clojure.spec.alpha$macroexpand_check invokeStatic "alpha.clj" 689]
[clojure.spec.alpha$macroexpand_check invoke "alpha.clj" 681]
[clojure.lang.AFn applyToHelper "AFn.java" 156]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.lang.Var applyTo "Var.java" 702]
[clojure.lang.Compiler checkSpecs "Compiler.java" 6889]
[clojure.lang.Compiler macroexpand1 "Compiler.java" 6907]
[clojure.lang.Compiler macroexpand "Compiler.java" 6972]
[clojure.lang.Compiler eval "Compiler.java" 7046]
[clojure.lang.Compiler load "Compiler.java" 7514]
[hiposfer.kamal.core$eval24441 invokeStatic "form-init4756483243476288592.clj" 1]
[hiposfer.kamal.core$eval24441 invoke "form-init4756483243476288592.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 7062]
[clojure.lang.Compiler eval "Compiler.java" 7025]
[clojure.core$eval invokeStatic "core.clj" 3206]
[clojure.core$eval invoke "core.clj" 3202]
[clojure.main$repl$read_eval_print__8572$fn__8575 invoke "main.clj" 243]
[clojure.main$repl$read_eval_print__8572 invoke "main.clj" 243]
[clojure.main$repl$fn__8581 invoke "main.clj" 261]
[clojure.main$repl invokeStatic "main.clj" 261]
[clojure.main$repl doInvoke "main.clj" 177]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__21980 invoke "interruptible_eval.clj" 87]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 657]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1965]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1965]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__22025$fn__22028
invoke
"interruptible_eval.clj"
222]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__22020
invoke
"interruptible_eval.clj"
190]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
As you can see this is a single exception but contains 2 different exceptions inside which is what I think might be causing the problem.
Hope it helps
from expound.
@carocad Thanks for looking into this!
I can replicate the same results as you, so we're on the same page 😄
I guess that both Cursive and expound are just printing every exception that they get their hands into thus causing a double printing
Unfortunately, I don't think Expound can resolve this. Expound is just a replacement for the default spec printer, but it doesn't control the exception that is thrown, or how exceptions are displayed.
AIUI, this is controlled by REPL configuration (in your case, Cursive may be controlling this, or perhaps some third-party library like pretty).
For example, here's a REPL with Expound that uses clj
and I get less verbose output:
(start with clj -Sdeps '{:deps {friendly {:git/url "https://gist.github.com/bhb/2686b023d074ac052dbc21f12f324f18" :sha "cbc5b3c73d4788a25570f125e5f2de23a3d2bf5f"}}}' -m friendly
)
[Rebel readline] Type :repl/help for online help info
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (require '[clojure.spec.test.alpha :as st])
nil
user=> (require '[expound.alpha :as expound])
nil
user=> (set! s/*explain-out* expound/printer)
#object[expound.alpha$printer 0x56b66a26 "expound.alpha$printer@56b66a26"]
user=> (st/instrument)
[expound.printer/indent expound.paths/prefix-path? expound.alpha/specs expound.paths/kvps-path? expound.alpha/value-in-context expound.printer/pprint-str expound.paths/kps-path? expound.problems/summary-form expound.printer/no-trailing-whitespace]
user=> (let [x])
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
-- Syntax error -------------------
([x])
^^^
should have additional elements. The next element ":args" should satisfy
any?
-- Relevant specs -------
:clojure.core.specs.alpha/bindings:
(clojure.spec.alpha/and
clojure.core/vector?
(clojure.spec.alpha/* :clojure.core.specs.alpha/binding))
-------------------------
Detected 1 error
#: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__2436 0x7976e536 "clojure.spec.alpha$regex_spec_impl$reify__2436@7976e536"], :value ([x]), :args ([x])}, compiling:(NO_SOURCE_PATH:1:1)
user=>
By any chance does your project load "pretty" or another library that displays errors differently? What happens if you disable those?
from expound.
I don't use boot myself, but I found this note on the pretty page:
Pretty is also incorporated into the ultra plugin, and is packaged as part of Boot.
https://github.com/AvisoNovate/pretty
Does your REPL happen to be started by boot? If so, it may be setting up this exception printing by default.
from expound.
@bhb yes I am using Aviso/pretty
for my exception handling.
Thanks for looking into this, I will mention it in their repo to get some help
from expound.
@carocad Thanks for bringing this to my attention. I'm going to close this for now since I don't think expound can fix this, but please reopen if you discover something different 😄
from expound.
Related Issues (20)
- Error reports returned as :cause string in an exception when produced by instrumentation within generative testing HOT 11
- allow passing options map to expound/expound-str HOT 1
- Improve grouping of spec errors HOT 2
- Unnecessary dependency on `cider-nrepl` HOT 1
- Regression of #3 HOT 4
- Easier editing of error messages
- `printer` has invalid spec HOT 2
- "Cannot convert path" on instrumentation failures in the wild HOT 4
- (cljs.spec.test.alpha/instrument) breaks expound due to wrong arity HOT 4
- should expound work anywhere s/explain works? - clojurescript error HOT 7
- Error in :ret check when using with Orchestra 2020.07.12-1 HOT 5
- Internal error in `lift-singleton-groups` when having a datomic db value in fn args HOT 13
- Crash bug when printing, if a datomic db is present and the spec fails HOT 19
- Feature inquiry: a convenience function for validating a value against a spec HOT 4
- Wrapped `s/keys` does not properly display unqualified keyword specs HOT 5
- ClassCastException from `expound-str` when running in AWS Lambda HOT 9
- Small *print-length* and/or *print-level* sometimes yield NPE HOT 5
- PersistentList cannot be cast to class Named HOT 3
- proposal : defmsg equivalent for arbitrary predicates HOT 15
- optional include location of the spec error in the message. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from expound.