Fork me on GitHub

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


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


we get a fail on the defn spec


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


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*


@raymcdermott do you read and eval input from user?


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))))


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


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


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


before I pass it to the REPL


but yes, that’s a legitimate option @jumar


@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])
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 "" 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 ...


thanks @alexmiller I’ll give it a shot later


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


I then have a web server to intermediate


And this takes request from a REPL client in the browser


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


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


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


I’ll keep fiddling but ideas welcome 🙂


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