如何在Clojure中访问异常的:cause、:via和:trace键?

25

我找不到访问异常的:cause, :via和:trace键的方法。

下面是代码:

(try
  (throw (IllegalArgumentException. "1"))
  (catch Exception e
    e))

输出:

#error{:cause "1",
       :via [{:type java.lang.IllegalArgumentException, :message "1", :at [user$eval4073 invokeStatic "form-init5592296091748814678.clj" 1]}],
       :trace [[user$eval4073 invokeStatic "form-init5592296091748814678.clj" 1]
               [user$eval4073 invoke "form-init5592296091748814678.clj" 1]
               [clojure.lang.Compiler eval "Compiler.java" 6927]
               [clojure.lang.Compiler eval "Compiler.java" 6890]
               [clojure.core$eval invokeStatic "core.clj" 3105]
               [clojure.core$eval invoke "core.clj" 3101]
               [clojure.main$repl$read_eval_print__7408$fn__7411 invoke "main.clj" 240]
               ....]}

附言: (:via e) 不起作用。


2
这只是一个方便的输出,用于堆栈跟踪/消息/原因。因此,您可以使用Java getters(https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#getStackTrace())检索它:`(seq(.getStackTrace e))` - leetwinski
2
同时,你可以阅读并编写这个记录来进行娱乐: (binding [*data-readers* {'error identity}] (let [err-data (read-string (pr-str e))] (:via err-data))) - leetwinski
2
(:通过 (clojure.edn/read-string (subs (pr-str e) 6))) - leetwinski
@leetwinski非常感谢!也许你应该把它写成一个答案,供新手参考。 - Ertuğrul Çetin
2
你绝对不应该使用pr-str/read-string来获取它 - 只需通过Java互操作直接访问数据或调用Clojure函数以获取它作为Clojure数据 - 请参见我的下面的答案。 - Alex Miller
1个回答

36

当 Clojure(JVM)发生异常时,它会抛出一个 Java Exception 对象。Clojure 将使用函数 Throwable->map 将其转换为数据,然后为您打印出来。您也可以自己调用该函数:

user=> (try (throw (Exception. "BOOM!")) 
         (catch Exception e 
           (Throwable->map e)))

{:cause "BOOM!",
 :via [{:type java.lang.Exception,
        :message "BOOM!",
        :at [user$eval1 invokeStatic "NO_SOURCE_FILE" 1]}],
 :trace [[user$eval1 invokeStatic "NO_SOURCE_FILE" 1] 
         ...]}
您可以直接使用返回数据的常规关键字访问器:
user=> (println (:cause *1) (first (:via *1)))
BOOM! {:type java.lang.Exception, :message BOOM!, :at [user$eval7 invokeStatic NO_SOURCE_FILE 4]}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接