Obtain a callstack in Clojure

前端 未结 1 1592
清歌不尽
清歌不尽 2021-01-01 13:42

When I run my Clojure programs and get an error during execution, I notice that the message printed by the REPL only contains the top level line number from the script I exe

相关标签:
1条回答
  • 2021-01-01 14:02

    The last Exception thrown is available in the *e var. You can print a stack trace by calling .printStackTrace on the Exception. It'll print line numbers if your Exception was thrown by source code in a file, or NO_SOURCE_FILE if it's from the REPL, like in my examples below.

    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) there's a function called pst that does the same thing. These stack traces are a bit nicer because some extraneous lines are removed.

    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
    

    Certain IDEs (e.g. SLIME for Emacs) will pop up the stack trace for you automatically. There are also some libraries for displaying and manipulating stacktraces, like clojure.stacktrace and clj-stacktrace.

    Stack trace handling seems to be an aspect of Clojure that's still being refined.

    0 讨论(0)
提交回复
热议问题