This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-20
Channels
- # announcements (1)
- # babashka (32)
- # beginners (100)
- # cider (43)
- # clj-kondo (4)
- # cljdoc (3)
- # cljs-dev (5)
- # cljsjs (2)
- # cljsrn (22)
- # clojure (170)
- # clojure-australia (27)
- # clojure-europe (25)
- # clojure-nl (3)
- # clojure-uk (76)
- # clojurescript (127)
- # conjure (14)
- # core-matrix (1)
- # cursive (9)
- # datomic (6)
- # defnpodcast (1)
- # emacs (32)
- # events (1)
- # expound (77)
- # fulcro (30)
- # graalvm (21)
- # graalvm-mobile (30)
- # helix (4)
- # honeysql (1)
- # hyperfiddle (1)
- # jackdaw (8)
- # jobs (6)
- # kaocha (1)
- # leiningen (4)
- # lsp (16)
- # malli (46)
- # meander (4)
- # off-topic (19)
- # pathom (10)
- # podcasts (1)
- # portal (2)
- # re-frame (7)
- # reagent (2)
- # releases (1)
- # remote-jobs (11)
- # rewrite-clj (8)
- # shadow-cljs (9)
- # tools-deps (243)
- # vim (1)
I can't get expound to work on clojurescript running on chrome. Can anyone help?
@quentin.leguennec1 Can you expand a bit on this? What have you tried? What are you expecting to see? And what do you see now?
@bbrinck Yes. I'm using https://github.com/nedap/speced.def and I'm expecting to see the expound formatted message in the chrome console when there is a spec mismatch. I have this preloaded:
(ns analis-desktop.preload
(:require
[js-deps-bundle]
[expound.alpha :as expound]
[cljs.spec.alpha :as s]
[cljs.repl :as repl]))
(println "requiring js bundle before re-frame-10x...")
(set! s/*explain-out* expound/printer)
(def devtools-error-formatter
"Uses cljs.repl utilities to format ExceptionInfo objects in Chrome devtools console."
#js{:header
(fn [object _config]
(when (instance? ExceptionInfo object)
(let [message (some->> (repl/error->str object)
(re-find #"[^\n]+"))]
#js["span" message])))
:hasBody (constantly true)
:body (fn [object _config]
#js["div" (repl/error->str object)])})
(defonce _
(some-> js/window.devtoolsFormatters
(.unshift devtools-error-formatter)))
(s/explain int? :hi)
correctly displays with the expound formatting
spec mismatchs display this:
REPL eval error
Execution error (ExceptionInfo) at (<cljs repl>:1).
Execution error (ExceptionInfo) at (<cljs repl>:1).
Validation failed
(I'm using emacs, lein, figwheel, chrome)
By “spec mismatchs”, do you mean the error that occurs when you call a specced function with invalid arguments?
Two things to try:
1. Can you double check the error handler is working? Perhaps by just raising some other ExpectionInfo
object in your code and making sure your custom formatter is invoked?
2. Can you remove speced.def
from the repro and see what happens when you use s/fdef
?
(ExceptionInfo. "hello")
doesn't do anything, neither to the repl on the chrome console
I'm testing 2. rn
oh nvm (throw (ExceptionInfo. "hello"))
correctly throws an error
no, it shows:
react_devtools_backend.js:2574 REPL eval error
Execution error (ExceptionInfo) at (<cljs repl>:1).
Execution error (ExceptionInfo) at (<cljs repl>:1).
hello
I see. So although there may be an issue with the Expound config, I think the first thing is to debug why (throw (ExceptionInfo. "hello"))
isn’t being formatted by the devtools-error-formatter
I see, thanks
devtools-error-formatter
, isn't called at all, console.log calls don't do anything in the :header function
Interesting. I wonder if the defonce
is being called correctly. Or if you can inspect the value of js/window.devtoolsFormatters
once the page is loaded and see what is in there.
It looks correct
#js[#js{:header #object[header], :hasBody #object[G__11224], :body #object[body]} #js{:header #object[header], :hasBody #object[G__11224], :body #...
It’s hard to say just from looking at what you showed above, since the values are opaque objects
Oh yes I see
Yep, I named the header function custom-header-function
and : #js[#js{:header #object[analis_desktop$preload$custom_header_function], :hasBody #object[G__11224], :body
Why unshift though? Can't I just make a new array?
Oh nvm, it's displaying my console.log calls now
Since s/window.devtoolsFormatters
is a mutable JS array, we need to mutate it with unshift. We could make a new array, but we’d need to assign it somewhere
Oh I see
Oh OK, that’s good to know that the console logs are printing. Do you see the custom message
somewhere? It might be useful to add some weird text to it to make sure it’s easy to see e.g. "--- debugging----"
Yeah it seems like the defonce _
call is not working
It works when I remove it
I got this now
I don't see the result of the :body call though
#js{:header
(fn custom-header-function [object _config]
(.log js/console "---debugging---" (instance? ExceptionInfo object))
(when (instance? ExceptionInfo object)
(let [message (some->> (repl/error->str object)
(re-find #"[^\n]+"))]
#js["span" message])))
:hasBody (constantly true)
:body (fn [object _config]
(.log js/console "hello")
#js["div" (repl/error->str object)])}
OK, maybe you can simplify by just printing out random values to make sure header and body are being shown.
Instead of #js["span" message]
, do #js["span" "test header"]
and instead of #js["div" (repl/error->str object)]
do #js["div" "test body"]
Yep that works
The console.log
call only runs when I expand the body but I guess it's intended
So I guess there's no issue in that part
So, if you put the old code back, then do something like (throw (ex-info "some error" {:a 1 :b 2}))
, then expand the body, you should see details about the error. Does that all work?
Yep that works
REPL eval error #error {:message "some error", :data {:a 1, 😛 2}}
OK, then next, can you do something like this (untested, I don’t have a Clojure repl handy)
(s/fdef my-inc
:args (s/cat :x number?))
(defn my-inc [x] (+ x 1))
Evaluating this in the repl doesn't throw anything:
(do
(s/fdef my-inc
:args (s/cat :x number?))
(defn my-inc [x] (+ x 1))
(my-inc "foo"))
I got this in the chrome console:
#error {:message
"Call to #'analis-des … not conform to spec."
, :data
{:cljs.spec.alpha/problems [
{…}
A standard ex-info message from what I understand, not formatted by expound
The devtools-error-formatter
code only sets the header and body, it won’t change what is displayed in the console itself.
Well there are several things going on, it seems
Got it. OK, so it looks to me that there are a few things going on here.
My guess is that if you removed that defonce
, it means that each time you eval this code, it’s adding an additional formatter, so you’re seeing the results of old and new formatters
It looks like for some reason, the following code isn’t taking effect (set! s/*explain-out* expound/printer)
. Can you double check that is being called? You might even copy/paste it into the body function to make sure it’s being called before you call repl/error->str
Or you could try
clojure
:body (fn [object _config]
#js["div" (binding [s/*explain-out* expound/printer]
(repl/error->str object))
])
Ok, I'll try this
@bbrinck I partially got it. I actually had to move the code away from the preload and it works even with the defonce
.
I still only have "Validation error" for speced, though, but I guess I should directly contact the author.
Thanks a lot!
It’s possible the issue is that specced
may need expound to be set up during macro-expansion time, which confusingly happens in Clojure, not Clojurescript.
i.e. you might have to set up a .cljc
file and then do something like
(require '[expound.alpha :as expound]) #?(:clj (set! clojure.spec.alpha/*explain-out* expound.alpha/printer))
And have that happen before you start using any specced
macros. That’s a total guess though.
Hmm I did that and the issue remains
It seems like it's rather chrome not displaying the complete message for speced specs though, because this gets printed in the REPL, and that looks like a expound string:
#error {:message "Validation failed", :data {:explanation "-- Spec failed --------------------\n\n :a\n\nshould satisfy\n\n string?\n\n-------------------------\nDetected 1 error\n", :spec-object #object[cljs$core$string_QMARK_], :spec cljs.core/string?, :quoted-spec cljs.core/string?, :faulty-value-object :a, :quoted-faulty-value a, :faulty-value a}}
If so, it doesn’t appear to be compatible with error->str
https://github.com/clojure/clojurescript/blob/a4673b880756531ac5690f7b4721ad76c0810327/src/main/cljs/cljs/repl.cljs#L229-L230
error->str
(or rather ex-str
, which is called by it) expects a normal spec error. If specced
is already changing the error, you’d need to adjust your handler to specifically deal with specced
data