从Clojure中的异步进程中捕获异常?

时间:2013-08-15 17:36:51

标签: clojure

假设我正在异步发送电子邮件,并希望我的程序继续执行。到目前为止,我一直在使用future进行此操作,但不幸的是,当电子邮件无法发送时,不会引发任何异常。

我明白,取消引用未来会引发ExecutionException,但是否定论将会失败。

有没有更好的方法来“开火”,而不会丢失异常信息?

2 个答案:

答案 0 :(得分:4)

我会使用处理程序函数来处理代理程序操作引发的异常:

(agent initial-state :error-handler handler-fn)

有关详细信息,请参阅(doc agent)(doc set-error-handler!)(doc set-error-mode!)initial-state这里可能只是nil,或者是一个包含一些记录数据的结构。

为方便起见,您希望email功能可用于sendsend-offsend-via):

(defn email [agent-state message] ...)

如果需要通知主线程有问题,则需要注意某些通道的通信。 (Java队列是一种可能性,core.async的通道是另一种。)处理程序函数然后可以通过该通道推送消息。

答案 1 :(得分:3)

不试试......

(def foo (future (Thread/sleep 5000) 
                 (throw (Exception. "bananas!")) 
                 (Thread/sleep 5000)))

(future-done? foo)
;=> false

5秒后......

(future-done? foo)
;=> true

@foo
;=> Exception bananas!  user/fn...

尝试......

(def bar (future (try (Thread/sleep 5000) 
                      (throw (Exception. "bananas!")) 
                      (Thread/sleep 5000) 
                      (catch Exception e (println "Oh, " (.getMessage e))))))

(future-done? bar)
;=> false

5秒后......

;=>Oh, bananas!

@bar
;=> nil