web-dev-qa-db-fra.com

Comment puis-je lever une exception dans Clojure?

Je souhaite lever une exception et avoir les éléments suivants:

(throw "Some text")

Cependant, il semble être ignoré.

46
Yazz.com

Vous devez envelopper votre chaîne dans un Throwable :

(throw (Throwable. "Some text"))

ou

(throw (Exception. "Some text"))

Vous pouvez également configurer un bloc try/catch/finally:

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

Session REPL:

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

clojure.contrib.condition fournit un moyen convivial Clojure de gérer les exceptions. Vous pouvez soulever des conditions avec des causes. Chaque condition peut avoir son propre gestionnaire.

Il y a un certain nombre d'exemples dans le source sur github .

Il est assez flexible, dans la mesure où vous pouvez fournir vos propres clés et paires de valeurs lors de la génération, puis décider quoi faire dans votre gestionnaire en fonction des clés/valeurs.

Par exemple. (manipuler l'exemple de code):

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

Vous pouvez alors avoir un gestionnaire pour :something-is-wrong:

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

Si vous souhaitez lever une exception et y inclure des informations de débogage (en plus d'une chaîne de message), vous pouvez utiliser la fonction intégrée ex-info .

Pour extraire les données de l'objet ex-info précédemment construit, utilisez ex-data .

Exemple de 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))

Dans un commentaire kolen mentionné slingshot , qui fournit des fonctionnalités avancées qui vous permettent non seulement de lancer des objets de type arbitraire (avec throw +), mais également d'utiliser une syntaxe de capture plus flexible pour inspecter les données à l'intérieur des objets lancés (avec essayez +). Exemples de le repo du projet :

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

math/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+))))
9
dskrvk