Occasionally you’ll hit an exception when calling into Java code and the REPL will tell you the message but not the stack trace:
user=> (java.util.Date. "foo") java.lang.IllegalArgumentException (NO_SOURCE_FILE:0)
The last exception is stored in *e by the REPL and you can use the Clojure stacktrace API to examine it more closely:
user=> (use 'clojure.stacktrace) nil user=> (print-stack-trace *e 5) clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException (NO_SOURCE_FILE:0) at clojure.lang.Compiler.eval (Compiler.java:4658) clojure.core/eval (core.clj:2035) clojure.main$repl__7403$read_eval_print__7415.invoke (main.clj:183) clojure.main$repl__7403.doInvoke (main.clj:200) clojure.lang.RestFn.invoke (RestFn.java:426)
Here I dumped just the top 5 frames of the top-level exception. But I really want the cause of the exception not the wrapper exception created in the compiler. You can dump all the traces in the chain like this:
user=> (print-cause-trace *e 3) clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException (NO_SOURCE_FILE:0) at clojure.lang.Compiler.eval (Compiler.java:4658) clojure.core/eval (core.clj:2035) clojure.main$repl__7403$read_eval_print__7415.invoke (main.clj:183) Caused by: java.lang.IllegalArgumentException: null at java.util.Date.parse (Date.java:598) java.util.Date.<init> (Date.java:255) user/eval (NO_SOURCE_FILE:225)
Or print only the root cause like this:
user=> (print-stack-trace (root-cause *e) 3) java.lang.IllegalArgumentException: null at java.util.Date.parse (Date.java:598) java.util.Date.<init> (Date.java:255) user/eval (NO_SOURCE_FILE:225)
Of course you can always just treat the *e as a Throwable and call normal Java methods on it too:
user=> (.printStackTrace *e) java.lang.IllegalArgumentException (NO_SOURCE_FILE:0) at clojure.lang.Compiler.eval(Compiler.java:4658) at clojure.core$eval__5254.invoke(core.clj:2035) at clojure.main$repl__7403$read_eval_print__7415.invoke(main.clj:183) at clojure.main$repl__7403.doInvoke(main.clj:200) at clojure.lang.RestFn.invoke(RestFn.java:426) at clojure.main$repl_opt__7449.invoke(main.clj:254) at clojure.main$main__7484.doInvoke(main.clj:341) at clojure.lang.RestFn.invoke(RestFn.java:402) at clojure.lang.Var.invoke(Var.java:355) at clojure.lang.AFn.applyToHelper(AFn.java:171) at clojure.lang.Var.applyTo(Var.java:476) at clojure.main.main(main.java:37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at jline.ConsoleRunner.main(ConsoleRunner.java:69) Caused by: java.lang.IllegalArgumentException at java.util.Date.parse(Date.java:598) at java.util.Date.<init>(Date.java:255) at user$eval__362.invoke(NO_SOURCE_FILE:249) at clojure.lang.Compiler.eval(Compiler.java:4642) ... 16 more
Happy hunting!