Получить callstack в Clojure
Когда я запускаю свои программы Clojure и получаю ошибку во время выполнения, я замечаю, что сообщение, напечатанное REPL, содержит только номер строки верхнего уровня из сценария, который я выполнил. Могу ли я получить его для сброса стека вызовов (который ссылается на различные номера строк кода Clojure)?
Например:
user=> (load-file "test.clj")
java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$eval134$fn (test.clj:206)
user=>
Было бы лучше, если бы я знал больше, чем просто вызов верхнего уровня (линия 206).1 ответ:
Последнее исключение доступно в
*e
ВАР. Вы можете распечатать трассировку стека, вызвав.printStackTrace
Для исключения. Он будет печатать номера строк, если ваше исключение было вызвано исходным кодом в файле, или NO_SOURCE_FILE, если это из REPL, как в моих примерах ниже.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
В Clojure 1.3 (alpha) есть функция под названием
pst
, которая делает то же самое. Эти трассировки стека немного лучше, потому что удаляются некоторые посторонние линии.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
Некоторые Иды (например, слизь для Emacs) автоматически появится трассировка стека. Существуют также некоторые библиотеки для отображения и манипулирования stacktraces, такие как clojure.stacktrace иclj-stacktrace .
Обработка трассировки стека, по-видимому, является одним из аспектов Clojure, который все еще уточняется.