Closed swannodette closed 9 years ago
@swannodette By "server side support", did you mean something upstream in the ClojureScript codebase? (Or, something in the Objective-C code in this repo?)
@mfikes I just landed some helpers in the ClojureScript cljs.source-map
namespace to make it easier to remap stack traces from REPLs.
From irc
dnolen mfikes: should maybe think about how we parse traces since ever engine is a little bit different dnolen mfikes: perhaps this should be the job of the REPL before passing it on to the generic REPL infrastructure
The V8 stacktrace format is documented here.
I find a couple of things interesting:
eval
near the bottom could defeat a naive parser.@swannodette Let me know if you'd like me to take a stab at rewriting the "symbol@file-url:line:column" JSC-style stack traces to look like V8 in the Objective-C code near here.
(That is, if you think that's the right direction and if you think that would help.)
@mfikes I think stack canonicalization should always happen on the Clojure side. And matching V8 isn't a goal, we want a Clojure representation that can easily be source mapped. Having this stuff in Clojure means it's more visible and that potential REPL writers can more easily understand the minimal set of functionality necessary for a good experience.
@swannodette Yes. I came to the same conclusion and came back to suggest that alternative. :)
Perhaps some conditional code here if :exception
?
@swannodette Also agree on non-V8 rep.
Hmm... stack canonicalization might be a challenge for REPLs that support arbitrary JavaScript engines. (For example, the browser REPL, or Weasel).
@mfikes I'm not too concerned about that. Multi-target REPLs will need to sort out the best way to do stack canonicalization themselves. Automatic source mapping of stack traces will be behind a REPL flag with the default set to false
.
@swannodette Landed a stab at the parsing aspect (feel free to revise).
For
(first (js/Date.))
It parses it apart into:
{:frames
'({:function "seq"
:file "/Users/mfikes/Documents/Projects/ambly/Clojure/out/goog/../cljs/core.js"
:line 4212
:column 17}
{:function "first"
:file "/Users/mfikes/Documents/Projects/ambly/Clojure/out/goog/../cljs/core.js"
:line 4242
:column 22})
:stack "Error: Fri Feb 06 2015 14:19:32 GMT-0500 (EST) is not ISeqable\nseq@file:///Users/mfikes/Documents/Projects/ambly/Clojure/out/goog/../cljs/core.js:4212:17\nfirst@file:///Users/mfikes/Documents/Projects/ambly/Clojure/out/goog/../cljs/core.js:4242:22\n\nglobal code"}
With the last set of changes, here is what you see in the REPL (note that there is now a convenience script/jscrepljs
to start up the Clojure(Script) half):
Mike-Fikess-MacBook-Pro:Clojure mfikes$ script/jscrepljs
To quit, type: :cljs/quit
ClojureScript:cljs.user> (first (js/Date.))
Error: Fri Feb 06 2015 20:42:42 GMT-0500 (EST) is not ISeqable
[{:function seq, :file /Users/mfikes/Documents/Projects/ambly/Clojure/.ambly_jsc_repl/goog/../cljs/core.js, :line 4212, :column 17} {:function first, :file /Users/mfikes/Documents/Projects/ambly/Clojure/.ambly_jsc_repl/goog/../cljs/core.js, :line 4242, :column 22}]
nil
Of note:
:value
is now just the "Error ... is not ISeqable portion".:stacktrace
is a vector of frames, prn
d and cleaned up below.:stacktrace
be a map containing :raw-stacktrace
and :frames
, or make :stacktrace
be the raw JSC string representation---compatible with existing tools in that it is a string?---and put the frames vector in a wholly new :frames
key or somesuch)[{:function "seq", :file "/Users/mfikes/Documents/Projects/ambly/Clojure/.ambly_jsc_repl/goog/../cljs/core.js" :line 4212 :column 17} {:function "first" :file "/Users/mfikes/Documents/Projects/ambly/Clojure/.ambly_jsc_repl/goog/../cljs/core.js" :line 4242 :column 22}]
Here is a little more detail with what I was seeing with ClojureScript master:
The Node.js REPL is producing line numbers that make sense when you go and open the files:
ClojureScript:cljs.user> (ffirst 1)
Error: 1 is not ISeqable
at Object.seq (/Users/mfikes/Documents/Projects/clojurescript2/.cljs_node_repl/cljs/core.cljs:727:20)
at Object.first (/Users/mfikes/Documents/Projects/clojurescript2/.cljs_node_repl/cljs/core.cljs:736:16)
at ffirst (/Users/mfikes/Documents/Projects/clojurescript2/.cljs_node_repl/cljs/core.cljs:1155:11)
Ambly's are off a bit (not off-by-one):
ClojureScript:cljs.user> (ffirst 1)
Error: 1 is not ISeqable
cljs.core/seq (.ambly_jsc_repl/cljs/core.cljs:711:4)
cljs.core/first (.ambly_jsc_repl/cljs/core.cljs:735:6)
cljs.core/ffirst (.ambly_jsc_repl/cljs/core.cljs:1151:0)
This issue has been resolved in this repo and ClojureScript master now supports.
ClojureScript has source map support at runtime on the client or this can be done on the server. Server side support needs a tiny push. This is probably the right way to do it. Then any JavaScript environment that's properly bootstrapped can send the stacktrace and the ClojureScript REPL can map it for you. This should probably be the default and be disable-able for environment likes Node.js that already have good source mapping support.