Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read clojure exceptions in REPL?

Tags:

clojure

Many times when I try to write some function I get exception. That is normal. In Java you can find place and reason why exception occures but in clojure exception texts just make me crazy. Is there some tips how to read exceptions in clojure and how to find where in code exception happens and why?

For example I will take some code:

(do
 (list?)
 (list? [])
 (list? '(1 2 3))
 (list? (defn f [] (do ())))
 (list? "a"))

when I call this function in REPL I will get

java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$list-QMARK- (NO_SOURCE_FILE:46)

which do not help me much to find the problem in second line. In little more complicated code it will give almost no information. (Of course it tells look at list? in some there is wrong number of arguments.) Is it wrong that I try to write code in REPL? How to read exception mesages in REPL? Is there way how to get better information about exceptions in REPL?

like image 626
boucekv Avatar asked Feb 19 '13 09:02

boucekv


2 Answers

You can use clojure.stacktrace: http://richhickey.github.com/clojure/clojure.stacktrace-api.html

Usage:

(use 'clojure.stacktrace)
(/ 1 0)
(e)

Output:

java.lang.ArithmeticException: Divide by zero
 at clojure.lang.Numbers.divide (Numbers.java:156)
    clojure.lang.Numbers.divide (Numbers.java:3691)
    user$eval954.invoke (NO_SOURCE_FILE:1)
    clojure.lang.Compiler.eval (Compiler.java:6511)
    clojure.lang.Compiler.eval (Compiler.java:6477)
    clojure.core$eval.invoke (core.clj:2797)
    clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
    clojure.main$repl$fn__6410.invoke (main.clj:266)
nil
like image 141
Marius Danila Avatar answered Nov 11 '22 20:11

Marius Danila


Acquire org.clojure/tools.trace.

user=> (use 'clojure.tools.trace)

Let's try a dotrace (changed up the order to make things more interesting):

user=> (dotrace [list?]
  #_=> (do
  #_=>  (list? [])
  #_=>  (list? '(1 2 3))
  #_=>  (list?)
  #_=>  (list? (defn f [] (do ())))
  #_=>  (list? "a"))
  #_=> )
IllegalStateException Can't dynamically bind non-dynamic var: clojure.core/list?
  clojure.lang.Var.pushThreadBindings (Var.java:353)

Hmm...

user=> (.setDynamic #'list?)
#'clojure.core/list? 

Let's try that again:

user=> (dotrace [list?]
  #_=>   (do
  #_=>   (list? [])
  #_=>   (list? '(1 2 3))
  #_=>   (list?)
  #_=>   (list? (defn f [] (do ())))
  #_=>   (list? "a")))
TRACE t1216: (list? [])
TRACE t1216: => false
TRACE t1217: (list? (1 2 3))
TRACE t1217: => true
TRACE t1218: (list?)
ArityException Wrong number of args (0) passed to: core$list-QMARK-  
  clojure.lang.AFn.throwArity (AFn.java:437)

Aha! Made it to (list?) before the exception.

like image 36
A. Webb Avatar answered Nov 11 '22 18:11

A. Webb