首页 > 解决方案 > 如何从 Clojure 异常中提取元数据?

问题描述

我刚刚开始学习 Clojure 并努力提取异常元数据。当我运行这个:

(try  
  (/ 1 0)  
  (catch Exception error (println error)))

正如预期的那样,我得到了一个 ArithmeticException。打印的堆栈跟踪如下所示:

#error {
 :cause Divide by zero
 :via
 [{:type java.lang.ArithmeticException
   :message Divide by zero
   :at [clojure.lang.Numbers divide Numbers.java 188]}]
 :trace
 [[clojure.lang.Numbers divide Numbers.java 188]
  [clojure.lang.Numbers divide Numbers.java 3901]
  ...
 ]}

对我来说它看起来像 a map,所以我尝试从:causewith中提取值(:cause error),但它的计算结果为nil

我怎样才能做到这一点?


更新:

挖了一下,发现#error {...}是一个java.lang.Throwable类,对吗?

我尝试使用 Java 互操作(.getCause error),但也返回nil。结果(.getMessage) error)确实返回“除以零”。

除了 ,还有其他方法可以从该类中获取特定属性.getMessage()吗?

标签: clojure

解决方案


Clojure 必须ex-message从异常ex-cause中检索消息并检索原因——如果有的话。的打印显示在#error这里有点误导,因为异常中实际上没有“原因”(在 Java 意义上.getCause),因为没有链接异常。

另一个有用的功能是Throwable->map将异常(所有异常都java.lang.Throwable在其根)转换为常规 Clojure 哈希映射,您可以在其上执行所有常规操作:

user=> (ex-message (try (/ 1 0) (catch Exception e e)))
"Divide by zero"
user=> (keys (Throwable->map (try (/ 1 0) (catch Exception e e))))
(:via :trace :cause)
user=> (:cause (Throwable->map (try (/ 1 0) (catch Exception e e))))
"Divide by zero"
user=> 

推荐阅读