在 Clojure 中捕获多个异常并以相同的方式处理它们
Catch multiple exceptions in Clojure and handle them the same
这个和this question有点类似,但是我想捕获多个异常,并统一处理。在Ruby,我可以写
begin
rand(2) == 0 ? ([] + '') : (foo)
rescue TypeError, NameError => e
puts "oops: #{e.message}"
end
我可以在 Clojure 中做同样的事情吗?现在我 let
一个函数并在每个 catch
主体中调用它。
目前还没有简单的内置解决方案,但是,open ticket。
您可以在 catch 块中手动编写 dispatch on type。
(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))))
(ns mastering.Whosebug
(:use
[slingshot.slingshot :only [try+]]))
(try+
; ...
(catch (comp #{TypeError NameError} class) _ "caught"))
The slingshot library 在 github 可用。
您也可以委托给本地函数,尽管它有点冗长:
(let [handle #(println %)]
(try
(throwing-op)
(catch TypeError e (handle e))
(catch NameError e (handle e))))
你也可以使用这个宏:
(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))))
这个和this question有点类似,但是我想捕获多个异常,并统一处理。在Ruby,我可以写
begin
rand(2) == 0 ? ([] + '') : (foo)
rescue TypeError, NameError => e
puts "oops: #{e.message}"
end
我可以在 Clojure 中做同样的事情吗?现在我 let
一个函数并在每个 catch
主体中调用它。
目前还没有简单的内置解决方案,但是,open ticket。
您可以在 catch 块中手动编写 dispatch on type。
(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))))
(ns mastering.Whosebug
(:use
[slingshot.slingshot :only [try+]]))
(try+
; ...
(catch (comp #{TypeError NameError} class) _ "caught"))
The slingshot library 在 github 可用。
您也可以委托给本地函数,尽管它有点冗长:
(let [handle #(println %)]
(try
(throwing-op)
(catch TypeError e (handle e))
(catch NameError e (handle e))))
你也可以使用这个宏:
(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))))