Fork me on GitHub

Cursive doesn't always correctly link line numbers in exceptions. For example, I'm in a project that contains compute.db.formulas namespace. The below exception highlights everything except the calls from that namespace.


It appears to have to do with the fact that the files are .cljc and not .clj.


On that ^, I think it'd be useful to highlight stacktrace lines that are a part of the current project/module.


Cursive actually does this with the code folding - by default lines from outside the project are folded. I might be able to extend that to highlighting, but I can’t highlight folded sections and Cursive also uses code folding to convert the JVM version to a Clojure-friendly version.


@kenny That’s odd, I’ll try to reproduce that, thanks.


After I changed the file extension to clj, it worked. I need cljc though.


Ok, I’ll fix that.


@cfleming Also in the same space, Spec instrumentation exceptions printed from the tests are not formatted at all. This makes reading these traces really difficult. I actually don't think this has to do with the clojure.test integration though because if I copy the test to the REPL and run it, the resulting exception is also not formatted.

Alex Miller (Clojure team)18:07:57

example? might be something we should fix in clojure.test and I'm not sure that's logged anywhere


@alexmiller Can you see the screenshot above?


It appears to be the exception-info formatting - it all is printed on one line.


The above one was particularly nasty because the first line says :path [:argm nil] which, at first, makes no sense. Buried in that text wall is an important piece of info that would've made it immediately obvious what the problem was - :reason "no method".


Even further off topic: it seems like multi-specs should print a similar error to s/keys when a key is missing. For example:

(s/explain (s/keys :req-un [::a]) {})
{} - failed: (contains? % :a)
=> nil
(defmulti example-spec :a)
=> #'compute.db.formulas-test/example-spec
(defmethod example-spec :example 
  (s/keys :req-un [::example]))
=> #object[clojure.lang.MultiFn 0x645f9f2 "clojure.lang.MultiFn@645f9f2"]
(s/explain (s/multi-spec example-spec :a) {})
{} - failed: no method at: [nil]
=> nil
The s/keys error is obvious - (contains? % :a). The multi-spec error is far less so - no method at: [nil].

Alex Miller (Clojure team)20:07:58

the key is not being used as a key, but as a function, and falling through to :default case is perfectly fine

Alex Miller (Clojure team)20:07:50

there may still be something more that can be done here, but this tool is more generic than you're assuming


Yes, it is more general but aren't keywords already special conditions for multi-specs?

Alex Miller (Clojure team)21:07:00

it's special for retagging but not for validation


Ah that's different. It feels like validation could also be special conditioned to provide much nicer errors.


If I was really really eager to have an “Extract function” automated refactoring, is there any path forward for me? Can I bribe you @cfleming?


@U04V32P6U I’m afraid bribery is not required, and it’s not something that anyone else could easily implement. Badgering might work though, it’s something I want myself and have been meaning to implement forever.


or implement it myself?


How do you guys pass system environment variables to a Local REPL? IntelliJ seems to have some odd pattern of reading in the environment vars. In the Run Config modal under the System Environment modal, I can see the env vars IntelliJ reads. I can update my PATH env var by changing it in my ~/.profile. However, if I add a new env var to my ~/.profile, IntelliJ won't read that in.


Adding env vars into /etc/environment seems to work.


Another example of an exception that is not linked.


@kenny Are you on the latest Cursive? I made some fixes there for the new 1.10.1 exceptions which include a path.


I'm on v1.8.2-eap4-2018.3. Had to downgrade to 2018.3. Too many problems with 2019 version: indexing issue, paren highlights, & random CPU spikes.


Yeah, 2019 has been really bad for issues affecting Cursive.


Ok, I’m going to do a pass over all those matching filters, I’ve received a bunch of examples to fix recently.


The Help > Check for updates didn't show any Cursive updates so I think that's the latest version. I'm running Clojure 1.10.1.


Yeah, that’s the latest one.


Is the above exception-info formatting a clojure or cursive issue?


I haven’t had time to look at it, but if it happens in a normal REPL too it’s likely to be Clojure.


Certain exception infos are printed nicely though. A simple example:


@kenny Are you using aviso/pretty to print your exceptions?


@cfleming Not sure. It may have been installed in that project. Can't recall which project that was now. Is that not how Cursive typically formats exceptions?


It looks like aviso/pretty to me - Cursive will use it if it’s available at runtime. I’ve fixed that for the next build, along with your other cljc case.


Oh, cool. It just needs to be on the classpath for Cursive to use it?


Well, Cursive won’t actually require the namespace. IIRC it checks to see whether the ns is loaded, and if so uses it. So there needs to be something that actually loads pretty first.


Yeah, it does this:

      (find-ns 'io.aviso.exception) ((find-var 'io.aviso.exception/write-exception) *e)
      (find-ns 'clj-stacktrace.repl) (do (require 'clojure.stacktrace)
                                         ((find-var 'clj-stacktrace.repl/pst)
                                          ((find-var 'clojure.stacktrace/root-cause) *e)))
      :else (let [writer (StringWriter.)
      etc etc...


Was there a reason to not use it if simply provided on the classpath?


Well, you can’t tell if something is on the classpath, except by trying to load it and catching the exception. I could do that in this case, I guess, since it’s only used when using the action to print the last exception.


Yep - that seems useful. Wouldn't need to always create a user.clj and require pretty.


Even a simple instrument exception prints nicely.