Comments (18)
Thanks very much for reporting this. It looks like there are a few problems here.
-
The relevant specs are not showing. Is there any information in
:via
in this case? Can you possibly share your specs? -
It looks like there is a bug with underlining (with the "^" character) in this case. It should not be so wide given the data itself is more compact.
-
The way that printing of values works is not configurable.
1 & 2 look like potential bugs to me, so I can fix them in the short term.
3 is something I'm very open to, but I need to give it a little more thought. Dynamic variables is one way to go, and the nice thing about dynamic vars is that it is easy to make minor adjustments (like not omitting data). OTOH, it might be more generally useful to refactor Expound so that users can easily build their own printer
function using some helper functions. Then again, maybe this is too much effort for basic configuration. I'll think more about it.
from expound.
Short discussion of goals on slack https://clojurians-log.clojureverse.org/clojure-spec/2017-07-17.html#inst-2017-07-17T18:09:19.667294Z
from expound.
The other thing that might (potentially) help here is if I could show the actually call site with the function and arg names. I'm not sure if that's possible though - something to look into.
from expound.
Ok, so, there's some confusion here, caused by me. I'll address your points each in turn.
-
I have tried testing this locally, in Clojure and ClojureScript, and have not reproduced the issue. The issue was reported to me by a teammate, but it seems like he wasn't on the latest expound/orchestra, so the
:via
wasn't available. IFF this shows up again and I can get a good repro case for it shall I then bring it back up. Sorry for the confusion. -
My fault again; the output was much longer, since it contained an authentication token which I snipped into
meow
. The underlining has been working just fine for me. -
This looks like it's the only thing we need to discuss at this point.
Thanks for the thoughtful replies and sorry again for the misdirection.
from expound.
Update on the first point: the spec that was being used was just a direct predicate, not any defined spec. That's why it wasn't showing any relevant specs. Still not a problem of expound, since there's no more info you can show, but it solves the mystery of why it didn't show up for my teammate.
user=> (require '[orchestra.spec.test :as st])
nil
user=> (defn foobar [x y z] x)
#'user/foobar
user=> (s/def :example/age pos-int?)
:example/age
user=> (s/fdef foobar :args (s/cat :x :example/age :y string? :z map?) :ret :example/age)
user/foobar
user=> (st/instrument `foobar)
[user/foobar]
user=> (foobar 10 "10" "10")
clojure.lang.ExceptionInfo: Call to #'user/foobar did not conform to spec:
form-init5171563085878295562.clj:1
-- Spec failed --------------------
Function arguments
(... ... "10")
^^^^
should satisfy
map?
-------------------------
Detected 1 error
from expound.
@jeaye Thanks very much for the clarification! I appreciate the follow up.
I've been chasing down some unrelated bugs, but I'm still thinking about this. Another third option occurred to me: I could provide a new printer named something like instrumentation-printer
that is optimized for instrumentation (so far, that only means not omitting values, but perhaps there are other changes I might make). I think that might be overkill for this case, but custom printers have been mentioned before (for instance, to make a public-facing error messages for an API), so it's something I'm keeping in mind.
from expound.
@jeaye I'm thinking more about how we'd use this. If this was configurable, do you expect that you would enable it globally for your project? Or using binding
to manually set it when the default printer failed to help locate the error?
from expound.
Whichever approach you choose: dynamic var, custom printer, or something else, my team will be using it globally in both our client and server. Orchestra runs globally and we want good spec errors globally, too!
from expound.
Excellent. Thanks for the information!
from expound.
@jeaye Can you try out version 0.2.2-SNAPSHOT? You can follow these instructions to set up a custom printer. Please let me know if it works for your project.
Thanks for suggesting this change!
from expound.
from expound.
Trying this now. Sorry for the delay!
from expound.
Yeah, this {:show-valid-values? true}
does the trick. Thanks so much. It also raises another problem, however, which imposes another request for configuration onto expound. With valid values not being elided, the spec explanations can be so long that Android's logging system cuts them off (it only allows like 10 lines or so).
My first thought was "No problem, I'll use a custom printer to do a with-out-str
on the default printer and then chunk the logs out to Android so I can see everything." Unfortunately, the current printing customization only allows for the specification of a pure :value-str-fn
. Perhaps I could do the logging in there and return an empty string, but I haven't given that a shot yet. Suggestions?
from expound.
Oh, to follow up, the :value-str-fn
only covers the rendering of the value. So it looks like I could override s/*explain-out*
myself, have it call expound/custom-printer
within a with-out-str
and then chunk that.
EDIT followup: To be complete, I've found a solution for this and I don't think expound should have to change anything. It's very much a platform-specific problem and other libraries, like orchestra, may want to use explain-str
or with-out-str
anyway. As such, I've worked around the Android / React Native limitation with the following:
(defn print-lines! [msg]
(doseq [line (clojure.string/split-lines msg)]
(println line)))
; Part of React Native
(def default-error-handler! (ocall js/ErrorUtils "getGlobalHandler"))
(defn init! []
(ocall js/ErrorUtils
"setGlobalHandler"
(fn [error fatal?]
(print-lines! (oget error "message"))
(let [new-error (js/Error. "See log for details")]
(when default-error-handler!
(default-error-handler! new-error fatal?)))))
(st/instrument)
(set! s/*explain-out* (expound/custom-printer {:show-valid-values? true})))
from expound.
I'm closing this, since the snapshot works exactly as expected. Thanks, again, for the help and I'm looking forward to a full 0.2.2
release. :)
from expound.
@jeaye Thanks very much for reporting this and for testing the fix!
from expound.
I've released Expound 0.3.0
from expound.
Alright! Awesome work.
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.