How can I get the stack or line number for error?
DogLooksGood opened this issue · 10 comments
When spec check failed, an error is raised, and I can see it in the browser console, but there's no line number or stack information.
I don't know if it is limited by the Clojure's pre
/post
?
Hi!
Thanks for reaching out. Since there are various ways of setting up clojurescript, I cannot know the exact conditions you have.
Could you try a couple experiments?
- Create a plain
defn
(notspeced/
), with a:pre
that fails - Create a plain
defn
that performs(throw (ex-info "example" {}))
in the middle of its body
Do those correctly report their line number and stack info?
I'm using shadow-cljs with the :browser
target.
Just have some experiments,
- Plain
defn
with:pre
that fails will have a proper stack. speced/def
with(throw (ex-info "" {}))
don't have a meaningful stack.- Plain
defn
with(throw (ex-info "" {}))
don't have a meaningful stack. - Plain
defn
with(throw (js/Error. ""))
have a proper stack.
So I think it could be related to how shadow-cljs works or how the stacktrace of ex-info
is generated.
I will turn to shadow-cljs for more information.
I wasn't familiar with those intricacies. Great to know thanks!
Feel free to share your findings here. I might also play with shadow-cljs out of curiosity.
@vemv what environment you are using, is it behave correctly in your case?
For developing libraries such as this one, I use the cljsbuild :node target. That's a pretty barebones setup, and I'm used to always have meaningless stacktraces there (for all kind of code: speced or not, :pre, js/Error or ex-info). Because they have no source mapping.
I do have a shadow-cljs app around though, I just don't happen to work with it too often. Will let you know if I find anything interesting.
If the error was not raised while loading the given script, and not caused by the code from repl, a meaningful stacktrace will be provided.
It's probably because of the :script
loader-mode provided by shadow-cljs. shadow-cljs has two ways for loading compiled js: :script
and :eval
.
The experiments I did will all work correctly if code is loaded via tag. But the :eval
way provides better performance and better experience with more use case, such as React Native.
Still don't know the difference between ex-info
and js/Error
.
Thanks! I also checked the discussion in Clojurians #shadow-cljs.
Accordingly I edited a bit your post above so I can remember these conclusions later too (I understand EN is not your first language).
I'll make sure to play with shadow-cljs soon. If changing ex-info
-> js/Error
is proven to be better, I'll change that.
Btw as you may have noticed, there are 3 pull requests open in this project, 2 of which are done. All of them are relevant for cljs projects, particularly the one that solves #70
Very likely sometime in January all those goodies will be released as speced.def
2.0!
You're right!
with js/Error
meaningful stacktrace + source mapping:
with ex-info
no niceties:
I'll fix this over the week.
If you're impatient, you can apply this patch https://gist.github.com/vemv/e9a7534a5bc7f277395add3e7c23a291 to https://github.com/nedap/utils.spec/tree/ca6097b013488ed6da4463a734c3132bb0e68b8e and make your project use that utils.spec patched version (speced.def depends on utils.spec)
I didn't notice this before is because for most case the error is not raised during loading. But as far as I use speced.def
, this become common.
I have given the topic good thought.
Because clojure.spec
is based on invoking arbitrary functions including those outside of my control, there are many sources that can throw an ex-info
during load time.
So, even if I committed the patch I attached above, you'd still run into occasional ex-info
s. Generally I try not to author or encourage solutions that don't fully solve a problem.
In this case, there are two possible solutions which appear to be complete:
- use
:loader-mode :script
- use
:loader-mode :eval
but initialize the app asynchronously- e.g.
(defn main [] (js/setTimeout myapp 0))
- suggested by the shadow-cljs author in Clojurians
- seems good to me, although maybe it can bring some new problems on its own.
- e.g.
The :loader-mode
differences don't appear to be documented right now, so I requested that. He says he will think about it: https://clojurians.slack.com/archives/C6N245JGG/p1578250009291400?thread_ts=1578218029.277500&cid=C6N245JGG