Fork me on GitHub
#clojure-spec
<
2018-05-30
>
genRaiy07:05:14

I’m trying to find a nicer way to report simple errors based on clojure’s core specs….

genRaiy07:05:34

for example if a user types in (defn foo 1)

genRaiy07:05:44

we get a fail on the defn spec

genRaiy07:05:17

how can I have the result as data rather than a string?

genRaiy07:05:47

is there a magic var I can set or some other compiler property?

Alex Miller (Clojure team)12:05:22

In the case of a spec error, you should get an ExceptionInfo where ex-data has the explain data

Alex Miller (Clojure team)12:05:00

Or you can hook s/*explain-out*

jumar12:05:43

@raymcdermott do you read and eval input from user?

jumar12:05:59

Than this could work (although not sure if that's an optimal way to do it)

(try (eval (read-string "(defn foo 1)")) (catch Exception e (ex-data (.getCause e))))

genRaiy12:05:17

I’m reading the results of evaluation via the PREPL which gives back a string for the :val key

jumar12:05:34

I'm not familiar with prepl so don't know then

genRaiy12:05:58

I’m trying to avoid having to run eval on every input

genRaiy12:05:12

before I pass it to the REPL

genRaiy12:05:41

but yes, that’s a legitimate option @jumar

genRaiy12:05:29

@alexmiller I’m using the PREPL from 1.10 and it would be nice (IMHO) if there was a property for spec fails

Alex Miller (Clojure team)13:05:12

I’m a little confused by what you’re saying. In the case of an exception, I would expect prepl to be converting the Throwable to data with Throwable->map which captures ex-data in a :data attribute.

Alex Miller (Clojure team)13:05:11

trying some things in the repl, I understand what you’re saying I think, although I don’t understand why

Alex Miller (Clojure team)13:05:12

oh, I’m testing with io-prepl and it’s happening due to the default valf of pr-str - is that what you’re using @raymcdermott?

👍 4
Alex Miller (Clojure team)13:05:01

if you use a valf of identity, then you’ll get back throwables as data

party-corgi 4
Alex Miller (Clojure team)14:05:21

Clojure 1.10.0-master-SNAPSHOT
user=> (require '[clojure.core.server :as ccs])
nil
user=> (ccs/io-prepl :valf identity)
(defn foo 1)
{:tag :ret, 
 :val {:cause "Call to clojure.core/defn did not conform to spec:\nIn: [1] val: 1 fails spec: :clojure.core.specs.alpha/arg-list ...", 
       :via [{:type clojure.lang.Compiler$CompilerException, 
              :message "clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform...", 
              :at [clojure.lang.Compiler checkSpecs "Compiler.java" 6891]} 
             {:type clojure.lang.ExceptionInfo, 
              :message "Call to clojure.core/defn did not conform ...", 
#_here        :data #:clojure.spec.alpha{:problems (
                {:path [:args :bs :arity-1 :args], 
								 :pred clojure.core/vector?, 
								 :val 1, 
								 :via ...
`

genRaiy14:05:11

thanks @alexmiller I’ll give it a shot later

genRaiy21:05:03

@alexmiller I could be doing it wrong but I’m using io-prepl as part of a socket-server like this…

genRaiy21:05:21

I then have a web server to intermediate

genRaiy21:05:05

And this takes request from a REPL client in the browser

genRaiy21:05:33

which send over strings that are then read and sent to the remote prepl

genRaiy21:05:33

Read failclojure.lang.LispReader$ReaderException: java.lang.RuntimeException: No reader function for tag object 1

genRaiy21:05:38

is this an abuse? Is there another option to read that is more compatible?

genRaiy21:05:54

I’ll keep fiddling but ideas welcome 🙂

genRaiy21:05:01

Read fail: clojure.lang.EdnReader$ReaderException: java.lang.RuntimeException: No reader function for tag object

Alex Miller (Clojure team)21:05:59

I haven’t put all these pieces together recently and don’t have time to look at it today. you might look at wrapping clj-server/remote-prepl for the client side?

Alex Miller (Clojure team)21:05:55

and since stuff is mostly char stream based, you might just want the defaults in io-prepl but to read on the remote-prepl valf side, not sure