42

pragnę wyjątek i mieć:Jak mogę rzucić wyjątek w Clojure?

(throw "Some text") 

Jednak wydaje się być ignorowane.

+2

'throw' rzuca instancji Java' Throwable'. Czy '(throw (Exception." Some text "))' działa? – dfan

+0

kiedy próbuję (rzut "Some text") otrzymuję ClassClassException, ponieważ String nie może być rzutowany na Throwable. Dziwne, że rzut jest "ignorowany" w twoim przypadku ... – mikera

Odpowiedz

68

Trzeba owinąć sznurek w Throwable:

(throw (Throwable. "Some text")) 

lub

(throw (Exception. "Some text")) 

Można założyć try/catch/finally zablokować, a także:

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

Sesja REPL:

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

Doskonała odpowiedź. Dzięki! – Zubair

8

clojure.contrib.condition zapewnia przyjazny dla środowiska sposób obchodzenia się z wyjątkami. Możesz podnosić kondycję z przyczynami. Każdy warunek może mieć swój własny moduł obsługi.

Istnieje wiele przykładów w source on github.

Jest dość elastyczny, ponieważ można podnieść swój własny klucz, wartości par przy podnoszeniu, a następnie zdecydować, co zrobić w treserze na podstawie kluczy/wartości.

E.g. (Maglowania przykładowy kod):

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

Można wtedy mieć obsługi dla :something-is-wrong:

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

Teraz jest ono zastępowane przez [proca] (https://github.com/scgilardi/slingshot) (pobrane z [Where Did Clojure.Contrib Go] (http: //dev.clojure.org/display/design/Where + Did + Clojure.Contrib + Go)) – kolen

7

Jeśli chcesz rzucić wyjątek i zawierać pewne informacje debugowania w nim (oprócz wiadomości ciąg), można użyć wbudowanej funkcji ex-info.

Aby wyodrębnić dane z wcześniej skonstruowanego obiektu ex-info, należy użyć ex-data.

Przykład z 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)) 

w komentarzu Kolen wspomnianym slingshot, która zapewnia zaawansowaną funkcjonalność, która pozwala nie tylko rzucać obiektów dowolnego typu (z rzutów +), ale również użyć bardziej elastyczną składnię catch do sprawdzania danych wewnątrz wyrzucanych obiektów (za pomocą try +). Przykłady z 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))) 

matematyka/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+)))) 
Powiązane problemy