2010-10-31 11 views
19

Wenn ich meine Clojure-Programme ausführen und während der Ausführung einen Fehler erhalte, bemerke ich, dass die Nachricht von der REPL gedruckt nur die oberste Zeilennummer aus dem Skript, das ich ausgeführt habe. Kann ich dafür sorgen, dass ein Aufruf-Stack (der auf die verschiedenen Zeilennummern des Clojure-Codes verweist) ausgegeben wird?Erhalten Sie einen Aufruf in Clojure

Zum Beispiel:

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

Es wäre schöner, wenn ich mehr als nur der Top-Level-Anruf weiß (Linie 206).

Antwort

28

Die letzte Ausnahme ist in der *e Var. Sie können eine Stapelüberwachung drucken, indem Sie .printStackTrace auf der Ausnahme aufrufen. Es wird Zeilennummern gedruckt, wenn Ihre Exception durch den Quellcode in einer Datei ausgelöst wurde, oder NO_SOURCE_FILE, wenn es von der REPL stammt, wie in meinen Beispielen unten.

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 

In Clojure 1.3 (alpha) gibt es eine Funktion pst genannt, die das gleiche tut. Diese Stapelspuren sind ein bisschen schöner, weil einige überflüssige Zeilen entfernt werden.

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 

Bestimmte IDEs (z SLIME für Emacs) automatisch den Stack-Trace für Sie Pop-up. Es gibt auch einige Bibliotheken zum Anzeigen und Manipulieren von Stacktraces, wie clojure.stacktrace und clj-stacktrace.

Stack Trace Handling scheint ein Aspekt von Clojure zu sein, der immer noch verfeinert wird.

+0

Funktioniert perfekt! :) – pauldoo

+0

Gibt es eine Möglichkeit, auf andere Ausnahmen als * e zuzugreifen? – mascip