Exception 获取stacktrace作为字符串

Exception 获取stacktrace作为字符串,exception,clojure,stack-trace,printstacktrace,Exception,Clojure,Stack Trace,Printstacktrace,我正在使用Clojure,我想得到一个可以记录的堆栈跟踪(理想情况下,我希望将其作为字符串) 我看到(.getStackTrace e)返回一个StackTraceElement[],但我不知道如何从中打印出有意义的内容。我的第二种方法是使用PrintWriter作为参数的(.printStackTrace e)(因为我知道这在Java中是可能的),但我似乎没有得到正确的语法 谢谢。使用clojure.repl.pst获取StackTrace,并将*err*绑定到java.io.StringWr

我正在使用Clojure,我想得到一个可以记录的堆栈跟踪(理想情况下,我希望将其作为字符串)

我看到
(.getStackTrace e)
返回一个
StackTraceElement[]
,但我不知道如何从中打印出有意义的内容。我的第二种方法是使用PrintWriter作为参数的
(.printStackTrace e)
(因为我知道这在Java中是可能的),但我似乎没有得到正确的语法


谢谢。

使用
clojure.repl.pst
获取StackTrace,并将
*err*
绑定到
java.io.StringWriter

(use '[clojure.repl :only (pst)])

(defmacro with-err-str
  "Evaluates exprs in a context in which *err* is bound to a fresh
  StringWriter.  Returns the string created by any nested printing
  calls."
  [& body]
  `(let [s# (new java.io.StringWriter)]
     (binding [*err* s#]
       ~@body
       (str s#))))

(try
  (/ 1 0)
  (catch Exception e
    (let [s (with-err-str (pst e 36))]
      (println "Error log:")
      (println s))))

如果number23\u cn的解决方案有点过分,那么这就是如何将.getStackTrace的结果用作字符串(然后可以打印、放入日志中,等等)


与noisesmith的回答相比,这里有一点改进。它没有留下一个懒惰的seq,并具有美化功能:

(apply str (interpose "\n" (.getStackTrace t)))

还有一个具有
打印堆栈跟踪
打印跟踪元素
和一些其他有用的功能。

您可以使用
而不使用str

(try
  (name nil)
  (catch Exception e
    (with-out-str (println e))))

您只需使用
clojure.core
中非常有用的
pr str
函数即可:

(捕获异常e
(l/错误“Ho no,异常:”(pr str e)))

工作起来很有魅力。只是我必须将第一条语句更改为(使用[clojure.repl:only(pst)])
(apply str(interpose“\n”(.getStackTrace t))
也非常有效。
(try
  (name nil)
  (catch Exception e
    (with-out-str (println e))))
#error {
 :cause nil
 :via
 [{:type java.lang.NullPointerException
   :message nil
   :at [my_app$fn__47429$fn__47430 invoke "my_app.clj" 30]}]
 :trace
 [[my_app$fn__47429$fn__47430 invoke "my_app.clj" 30]
  [my_app$my_func invokeStatic "my_app.clj" 13]
  [my_app$my_func invoke "my_app.clj" 10]
  [my_app$other_func$fn__29431 invoke "my_app.clj" 19]
  [my_app$other_func_BANG_ invokeStatic "my_app.clj" 28]
  [my_app$other_func_BANG_ invoke "my_app.clj" 27]
  [my_app$yet_another_func invokeStatic "my_app.clj" 40]
  [my_app$yet_another_func invoke "my_app.clj" 37]
  [clojure.core$fn__8072$fn__8074 invoke "core.clj" 6760]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__7839 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__7839 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__7781$G__7776__7794 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6748]
  [clojure.core$fn__8072 invokeStatic "core.clj" 6750]
  [clojure.core$fn__8072 invoke "core.clj" 6750]
  [clojure.core.protocols$fn__7860$G__7855__7869 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6776]
  [clojure.core$reduce_kv invoke "core.clj" 6767]
  [my_app$yet_another_func invokeStatic "data_streamer.clj" 48]
  [my_app$yet_another_func invoke "data_streamer.clj" 47]
  [my_app$other_func invokeStatic "data_streamer.clj" 66]
  [my_app$other_func invoke "data_streamer.clj" 58]
  [my_app$other_func$fn__48385 invoke "my_app.clj" 73]
  [clojure.core.async$thread_call$fn__6553 invoke "async.clj" 442]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1135]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 635]
  [java.lang.Thread run "Thread.java" 844]]}