42

Tôi muốn ném một ngoại lệ và có những điều sau đây:Làm cách nào để tôi có thể ném ngoại lệ trong Clojure?

(throw "Some text") 

Tuy nhiên có vẻ như bị bỏ qua.

+2

'throw' ném trường hợp của Java' Throwable'. Có '(ném (ngoại lệ." Một số văn bản "))' làm việc? – dfan

+0

khi tôi thử (ném "Một số văn bản") Tôi nhận được một ClassClassException vì String không thể được đúc thành Throwable. Vì vậy, nó là kỳ quặc rằng ném được "bỏ qua" trong trường hợp của bạn .... – mikera

Trả lời

68

Bạn cần phải quấn dây của bạn trong một Throwable:

(throw (Throwable. "Some text")) 

hoặc

(throw (Exception. "Some text")) 

Bạn có thể thiết lập một try/catch/finally cũng như:

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

REPL phiên:

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

Brilliant câu trả lời. Cảm ơn! – Zubair

8

clojure.contrib.condition cung cấp phương tiện xử lý ngoại lệ thân thiện với Clojure. Bạn có thể tăng conditons với nguyên nhân. Mỗi điều kiện có thể có trình xử lý riêng.

Có một số ví dụ trong số source on github.

Khá linh hoạt, trong đó bạn có thể cung cấp cặp khóa, giá trị của riêng mình khi tăng và sau đó quyết định việc cần làm trong trình xử lý dựa trên khóa/giá trị.

Ví dụ: (Mangling mã ví dụ):

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

Sau đó bạn có thể có một handler cho :something-is-wrong:

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

Bây giờ nó được thay thế bằng [súng cao su] (https://github.com/scgilardi/slingshot) (lấy từ [Clojure.Contrib Go] ở đâu (http: //dev.clojure.org/display/design/Nơi + Đã + Clojure.Contrib + Go)) – kolen

7

Nếu bạn muốn ném một ngoại lệ và bao gồm một số thông tin gỡ lỗi trong nó (ngoài nhắn chuỗi), bạn có thể sử dụng chức năng được xây dựng trong ex-info.

Để trích xuất dữ liệu từ đối tượng thông tin cũ được tạo trước đó, hãy sử dụng ex-data.

Ví dụ từ 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)) 

Trong một bình luận kolen nêu slingshot, cung cấp chức năng tiên tiến cho phép bạn không chỉ để ném các đối tượng của kiểu bất kỳ (với ném +), mà còn sử dụng một cú pháp bắt linh hoạt hơn để kiểm tra dữ liệu bên trong các đối tượng được ném (với try +). Ví dụ từ the project repo:

tensor/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))) 

toán/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+)))) 
Các vấn đề liên quan