简体   繁体   English

如何有效地捕获不同功能的相同异常?

[英]How to catch the same exception for different functions efficiently?

The following works in REPL, in case the database is down I get the map back. 在REPL中,以下工作方式可以在数据库关闭的情况下恢复地图。

(try
 (insert-table "db" "table" {:id 1 :text "text"}) 
 (catch Exception e {:err "can't connect to database"}))

I though I could write a function that takes a db operation and wrap it with a (try). 我虽然可以编写一个函数,该函数接受db操作并用(try)包装。

(defn catch-db-connection-errors
  [db_operation]
  (try
    (db_operation)
    (catch Exception e {:err "can't connect to database"})))

It does not catch the exception though. 它没有捕获到异常。 I might just overlook something very simple... 我可能会忽略一些非常简单的事情...

The problem is that the form you pass in as an argument (eg (insert-table "db" "table" {:id 1 :text "text"}) ) is evaluated before the function is called, and the resulting value is passed into the function. 问题在于,在调用函数之前先评估您作为参数传递的形式(例如(insert-table "db" "table" {:id 1 :text "text"}) ),然后传递结果值进入功能。 To use another example, if you write (println (+ 1 1)) , Clojure will first evaluate (+ 1 1) to get 2 , and then will call (println 2) . 再举一个例子,如果您编写(println (+ 1 1)) ,Clojure将首先求值(+ 1 1)以获得2 ,然后调用(println 2) So if an exception is thrown in your DB code, it's before the catch-db-connection-errors function is called and thus outside the try form. 因此,如果在您的数据库代码中引发了异常,则该异常是在catch-db-connection-errors函数被调用之前并因此在try表单之外。

What you want is a macro, which thankfully is something Clojure is great at. 您想要的是一个宏,值得庆幸的是Clojure擅长于此。

(defmacro catch-db-connection-errors [& db-operations]
  `(try
    ~@db-operations
    (catch Exception e {:err "can't connect to database"})))

This allows you to pass in however many database-handling forms you want and wraps them in your try-catch pair. 这使您可以传递所需的许多数据库处理形式,并将它们包装在try-catch对中。

(Incidentally, you might want to catch something a little more specific than Exception, or else you could end up catching exceptions you don't intend do. But of course that's beside the point here.) (顺便说一句,您可能想捕获比Exception更具体的内容,否则您可能最终捕获到了您不打算做的异常。但是,这当然不重要。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM