2010-10-31 11 views
19

Cuando ejecuto mis programas Clojure y obtengo un error durante la ejecución, noto que el mensaje impreso por el REPL solo contiene el número de línea de nivel superior del script que ejecuté. ¿Puedo hacer que descargue una pila de llamadas (que hace referencia a los distintos números de línea del código de Clojure)?Obtenga un paquete de llamadas en Clojure

Por ejemplo:

user=> (load-file "test.clj") 
java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$eval134$fn (test.clj:206) 
user=> 

Sería mejor si sabía algo más que la llamada de nivel superior (línea 206).

Respuesta

28

La última excepción lanzada está disponible en *e var. Puede imprimir un seguimiento de pila llamando al .printStackTrace en la excepción. Imprimirá los números de línea si su excepción fue lanzada por código fuente en un archivo, o NO_SOURCE_FILE si es de REPL, como en mis ejemplos a continuación.

Clojure 1.2.0 
user=> (throw (Exception. "FOO")) 
java.lang.Exception: FOO (NO_SOURCE_FILE:0) 
user=> *e 
#<CompilerException java.lang.Exception: FOO (NO_SOURCE_FILE:0)> 
user=> (.printStackTrace *e) 
java.lang.Exception: FOO (NO_SOURCE_FILE:0) 
     at clojure.lang.Compiler.eval(Compiler.java:5440) 
     at clojure.lang.Compiler.eval(Compiler.java:5391) 
     at clojure.core$eval.invoke(core.clj:2382) 
     at clojure.main$repl$read_eval_print__5624.invoke(main.clj:183) 
     at clojure.main$repl$fn__5629.invoke(main.clj:204) 
     at clojure.main$repl.doInvoke(main.clj:204) 
     at clojure.lang.RestFn.invoke(RestFn.java:422) 
     at clojure.main$repl_opt.invoke(main.clj:262) 
     at clojure.main$main.doInvoke(main.clj:355) 
     at clojure.lang.RestFn.invoke(RestFn.java:398) 
     at clojure.lang.Var.invoke(Var.java:361) 
     at clojure.lang.AFn.applyToHelper(AFn.java:159) 
     at clojure.lang.Var.applyTo(Var.java:482) 
     at clojure.main.main(main.java:37) 
Caused by: java.lang.Exception: FOO 
     at user$eval1.invoke(NO_SOURCE_FILE:1) 
     at clojure.lang.Compiler.eval(Compiler.java:5424) 
     ... 13 more 
nil 

En Clojure 1.3 (alfa) hay una función llamada pst que hace lo mismo. Estos rastros de pila son un poco más agradables porque se eliminan algunas líneas extrañas.

Clojure 1.3.0-master-SNAPSHOT 
user=> (throw (Exception. "FOO")) 
Exception FOO user/eval1 (NO_SOURCE_FILE:1) 
user=> (pst) 
Exception FOO 
     user/eval1 (NO_SOURCE_FILE:1) 
     clojure.lang.Compiler.eval (Compiler.java:5998) 
     clojure.lang.Compiler.eval (Compiler.java:5965) 
     clojure.core/eval (core.clj:2652) 
     clojure.core/eval (core.clj:-1) 
     clojure.main/repl/read-eval-print--5575 (main.clj:178) 
     clojure.main/repl/fn--5580 (main.clj:199) 
     clojure.main/repl (main.clj:199) 
     clojure.main/repl-opt (main.clj:257) 
     clojure.main/main (main.clj:350) 
     clojure.lang.Var.invoke (Var.java:361) 
     clojure.lang.Var.applyTo (Var.java:482) 
nil 

Ciertos IDE (por ejemplo, SLIME para Emacs) mostrarán el seguimiento de pila automáticamente. También hay algunas bibliotecas para mostrar y manipular stacktraces, como clojure.stacktrace y clj-stacktrace.

El manejo de traza de pila parece ser un aspecto de Clojure que aún se está refinando.

+0

¡Funciona a la perfección! :) – pauldoo

+0

¿Hay alguna manera de acceder a excepciones pasadas, que no sean * e? – mascip

Cuestiones relacionadas