[英]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.