42

我想拋出一個異常,並具備以下條件:我如何在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

回答

68

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

8

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

7

如果你想拋出一個異常,包括它的一些調試信息(除了消息字符串),您可以使用內置的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+))))