Reputation: 17422
This is a bit similar to this question, but I want to catch multiple exceptions and handle them all the same. In Ruby, I can write
begin
rand(2) == 0 ? ([] + '') : (foo)
rescue TypeError, NameError => e
puts "oops: #{e.message}"
end
Can I do the same in Clojure? For now I let
a function and just call it in each catch
body.
Upvotes: 2
Views: 917
Reputation: 2844
You can also use this macro:
(defmacro try*
"Macro to catch multiple exceptions with one catch body.
Usage:
(try*
(println :a)
(println :b)
(catch* [A B] e (println (class e)))
(catch C e (println :C))
(finally (println :finally-clause)))
Will be expanded to:
(try
(println :a)
(println :b)
(catch A e (println (class e)))
(catch B e (println (class e)))
(catch C e (println :C))
(finally (println :finally-clause)))
"
[& body]
(letfn [(catch*? [form]
(and (seq form)
(= (first form) 'catch*)))
(expand [[_catch* classes & catch-tail]]
(map #(list* 'catch % catch-tail) classes))
(transform [form]
(if (catch*? form)
(expand form)
[form]))]
(cons 'try (mapcat transform body))))
credits https://gist.github.com/Gonzih/5814945
Upvotes: 0
Reputation: 45836
You could also delegate to a local function, although it gets a little verbose:
(let [handle #(println %)]
(try
(throwing-op)
(catch TypeError e (handle e))
(catch NameError e (handle e))))
Upvotes: 2
Reputation: 16060
(ns mastering.stackoverflow
(:use
[slingshot.slingshot :only [try+]]))
(try+
; ...
(catch (comp #{TypeError NameError} class) _ "caught"))
The slingshot library is available on github.
Upvotes: 8
Reputation: 3538
There is no simple built-in solution for that yet, however, there is an open ticket.
You can write a dispatch on type in the catch block by hand.
(try
(do-dangerous-operation-here)
(catch Exception e
(condp (fn [cs t] (some #(instance? % t) cs)) e
[IllegalStateException IllegalArgumentException]
(println "Either illegal state or illegal argument!")
[java.sql.SQLException]
(println "Sql error!")
;; whe pass through the exception when not handled
(throw e))))
Upvotes: 1