sanel / monroe

Clojure nREPL client for Emacs
161 stars 21 forks source link

Stacktrace lost after first exception #8

Closed yayitswei closed 9 years ago

yayitswei commented 9 years ago

After the first exception, the stacktraces no longer display in the buffer for subsequent exceptions. Do you know what's causing this?

user=> uehotanuehaostnuh
CompilerException java.lang.RuntimeException: Unable to resolve symbol: uehotanuehaostnuh in this context, compiling:(/private/var/folders/4x/mt4fz1c56797b2c8bs5c8x1m0000gn/T/form-init516450021019911153.clj:1:195) 
user=> clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: uehotanuehaostnuh in this context, compiling:(/private/var/folders/4x/mt4fz1c56797b2c8bs5c8x1m0000gn/T/form-init516450021019911153.clj:1:195)
                                Compiler.java:6464 clojure.lang.Compiler.analyze
                                Compiler.java:6406 clojure.lang.Compiler.analyze
...
nil
user=> uhtenoaseuhau
user=> nil
user=> 
sanel commented 9 years ago

Yes, this depends how exceptions are sent. Sometimes they are sent on standard out, sometimes as exception tag and sometimes both. Initial version didn't have this implemented correctly but the next one got it, so it isn't enabled by default to retain old behavior.

To enable it, just set monroe-detail-stacktraces to true, like:

(setq monroe-detail-stacktraces t)

Does this solves your problem?

yayitswei commented 9 years ago

I have monroe-detail-stacktraces enabled, but disabling it makes the first stacktrace go away.

user=> (+ 1 2)
3
user=> uhteoanuh
user=> 1
1

So I guess monroe just isn't displaying errors correctly for me. How does it send exceptions to the buffer?

sanel commented 9 years ago

Hm... that is odd. What application are you using? Or maybe leiningen version?

I just checked on Leiningen 2.4.2 with raw REPL and here what I'm getting:

dsdsd
CompilerException java.lang.RuntimeException: Unable to resolve symbol: dsdsd in this context, compiling:(NO_SOURCE_PATH:0:0) 
user=> clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: dsdsd in this context, compiling:(NO_SOURCE_PATH:0:0)
                                Compiler.java:6464 clojure.lang.Compiler.analyze
                                Compiler.java:6406 clojure.lang.Compiler.analyze
                                Compiler.java:6707 clojure.lang.Compiler.eval
                                Compiler.java:6666 clojure.lang.Compiler.eval
                                     core.clj:2927 clojure.core/eval
                                      main.clj:239 clojure.main/repl[fn]
                                      main.clj:239 clojure.main/repl[fn]
                                      main.clj:257 clojure.main/repl[fn]
                                      main.clj:257 clojure.main/repl
                                  RestFn.java:1096 clojure.lang.RestFn.invoke
                         interruptible_eval.clj:56 clojure.tools.nrepl.middleware.interruptible-eval/evaluate[fn]
                                      AFn.java:152 clojure.lang.AFn.applyToHelper
                                      AFn.java:144 clojure.lang.AFn.applyTo
                                      core.clj:624 clojure.core/apply
                                     core.clj:1862 clojure.core/with-bindings*
                                   RestFn.java:425 clojure.lang.RestFn.invoke
                         interruptible_eval.clj:41 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
                        interruptible_eval.clj:171 clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval[fn]
                                     core.clj:2402 clojure.core/comp[fn]
                        interruptible_eval.clj:138 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
                                       AFn.java:22 clojure.lang.AFn.run
                      ThreadPoolExecutor.java:1145 java.util.concurrent.ThreadPoolExecutor.runWorker
                       ThreadPoolExecutor.java:615 java.util.concurrent.ThreadPoolExecutor$Worker.run
                                   Thread.java:744 java.lang.Thread.run
Caused by: java.lang.RuntimeException: Unable to resolve symbol: dsdsd in this context
                                     Util.java:221 clojure.lang.Util.runtimeException
                                Compiler.java:6940 clojure.lang.Compiler.resolveIn
                                Compiler.java:6884 clojure.lang.Compiler.resolve
                                Compiler.java:6845 clojure.lang.Compiler.analyzeSymbol
                                Compiler.java:6427 clojure.lang.Compiler.analyze
nil
user=>

and I'm able to repeat this indefinitely.

yayitswei commented 9 years ago

Your question helped me discover that the problem only exists in two of my projects. The problem appears both when connecting to a REPL started from lein repl (2.5.0) and an embedded tools.nrepl (0.2.5) REPL.

Interestingly, other projects that use the same lein and tools.nrepl version seem to work fine.

Still investigating..

yayitswei commented 9 years ago

A bit more info: the problem seems to crop up after running lein uberjar; lein run. It goes away if I clean and then run lein run.

Do you know why creating an uberjar would have an effect on whether exceptions are printed?

Also, a side question: if you left monroe-detail-stacktraces as false, how do view the last exception's stacktrace, if you decide to investaget further?

sanel commented 9 years ago

Honestly, not sure. I presume that lein run would pick up jar generated by uberjar and maybe uberjar would strip out the code or do some optimizations (dumb guessing). Can you check with Cider please and let me know does it behave the same?

Also, a side question: if you left monroe-detail-stacktraces as false, how do view the last exception's stacktrace, if you decide to investaget further?

Monroe uses some tricks to get the full stacktrace from the last exception (by trying to load clj-stacktrace then fallback to clojure.stacktrace), but in general calling something like:

(clojure.stacktrace/print-stack-trace *e)

will do the job

sanel commented 9 years ago

Sorry, I accidentally closed this ticked :) Reopening it again.

yayitswei commented 9 years ago

Nice, (clojure.stacktrace/print-stack-trace *e) works for me. A shortcut for that might be nice-- how would I go about writing one?

I'll check with Cider when I get around to installing and configuring it (part of the reason for using Monroe was the ease of started). For now, feel free to close the issue since it's nonblocking.

Thanks for your help @sanel!

sanel commented 9 years ago

A shortcut for that might be nice-- how would I go about writing one?

You can assign key to this code:

  (monroe-input-sender
   (get-buffer-process monroe-repl-buffer)
   "(clojure.stacktrace/print-stack-trace *e))"))

This is temporal solution, as things could be changed in the future when multiple session support is added.

Thanks for your help

You're welcome! Let me know if you find other issues.