我如何在Clojure中抛出异常?

问题描述:

我想抛出一个异常,并具备以下条件:我如何在Clojure中抛出异常?

(throw "Some text") 

但是它似乎被忽略。

+2

'throw'抛出的Java'Throwable'的实例。是否(抛出(例外。“一些文本”))工作? – dfan 2011-03-28 13:54:30

+0

当我尝试(抛出“一些文本”)我得到一个ClassClassException,因为字符串不能转换为Throwable。所以这是很奇怪的是,在你的情况下投掷被“忽略”...... – mikera 2011-03-28 16:25:24

你需要用你的字符串在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 session:

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

明智的答案。谢谢! – Zubair 2011-03-28 19:45:45

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*))) 
+4

现在它被替换为[弹弓](https://github.com/scgilardi/slingshot)(取自[Where Did Clojure.Contrib Go](http://dev.clojure。组织/显示/设计/在哪里+难道+ Clojure.Contrib + GO)) – kolen 2013-05-13 19:26:23

如果你想抛出一个异常,包括它的一些调试信息(除了消息字符串),您可以使用内置的ex-info函数。

要从先前构建的ex-info对象中提取数据,请使用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,它提供了先进的功能,使您不仅抛出任意类型的对象(与抛+),而且还使用了更灵活的捕捉语法检查抛出的对象中的数据(使用try +)。从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+))))