如何在Clojure中抛出异常?

时间:2011-03-28 13:44:04

标签: exception exception-handling clojure functional-programming

我希望抛出异常并拥有以下内容:

(throw "Some text")

然而它似乎被忽略了。

3 个答案:

答案 0 :(得分:75)

您需要将字符串包装在Throwable

(throw (Throwable. "Some text"))

(throw (Exception. "Some text"))

您也可以设置try / catch / finally块:

(defn myDivision [x y]
  (try
    (/ x y)
    (catch ArithmeticException e
      (println "Exception message: " (.getMessage e)))
    (finally 
      (println "Done."))))

REPL会议:

user=> (myDivision 4 2)
Done.
2
user=> (myDivision 4 0)
Exception message:  Divide by zero
Done.
nil

答案 1 :(得分:10)

clojure.contrib.condition提供了一种Clojure友好的处理异常的方法。你可以提出原因的条件。每个条件都有自己的处理程序。

source on github中有很多例子。

它非常灵活,因为您可以在提升时提供自己的键值对,然后根据键/值决定在处理程序中执行的操作。

E.g。 (修改示例代码):

(if (something-wrong x)
  (raise :type :something-is-wrong :arg 'x :value x))

然后,您可以拥有:something-is-wrong的处理程序:

(handler-case :type
  (do-non-error-condition-stuff)
  (handle :something-is-wrong
    (print-stack-trace *condition*)))

答案 2 :(得分:9)

如果要抛出异常并在其中包含一些调试信息(除了消息字符串),您还可以使用内置的ex-info函数。

要从先前构建的ex信息对象中提取数据,请使用ex-data

来自clojuredocs的例子:

(try
  (throw 
    (ex-info "The ice cream has melted!" 
       {:causes             #{:fridge-door-open :dangerously-high-temperature} 
        :current-temperature {:value 25 :unit :celcius}}))
  (catch Exception e (ex-data e))

在评论中,kolen提到了slingshot,它提供了高级功能,不仅可以抛出任意类型的对象(使用throw +),还可以使用更灵活的catch语法来检查抛出对象内的数据(试试+)。 the project repo的示例:

张量/ parse.clj

(ns tensor.parse
  (:use [slingshot.slingshot :only [throw+]]))

(defn parse-tree [tree hint]
  (if (bad-tree? tree)
    (throw+ {:type ::bad-tree :tree tree :hint hint})
    (parse-good-tree tree hint)))

数学/ expression.clj

(ns math.expression
  (:require [tensor.parse]
            [clojure.tools.logging :as log])
  (:use [slingshot.slingshot :only [throw+ try+]]))

(defn read-file [file]
  (try+
    [...]
    (tensor.parse/parse-tree tree)
    [...]
    (catch [:type :tensor.parse/bad-tree] {:keys [tree hint]}
      (log/error "failed to parse tensor" tree "with hint" hint)
      (throw+))
    (catch Object _
      (log/error (:throwable &throw-context) "unexpected error")
      (throw+))))