期货和装货文件中的异常处理

时间:2013-04-24 16:25:21

标签: clojure

我希望我的clojure程序有一个可以运行的脚本目录 - 每个脚本都是我用load-file执行的clojure代码。这将在未来发生,以便脚本在其自己的线程中运行。

问题是我从未看到脚本中的任何错误消息。如果脚本失败,则无法知道出了什么问题。我认为这是因为未来的线程中没有异常处理。我可以将异常处理放入脚本中,如下所示,它可以工作:

;; script code    
(try

(println (/ 10 0))

(catch Exception e
  (println "Exception: " (.getMessage e))))

但是,我宁愿在加载文件周围加上异常处理,以便我不必在脚本本身中进行异常处理:

(defn handleexes [f]
  (try
    (f)
    (catch Exception e
       (println "exception: " (.getMessage e)))))

(defn start-script-play [name]
  (println "starting script: " name)
  (let [f (future (handleexes (load-file (str "./scripts/" name))))]
    (swap! scripts (fn [s] (assoc s name f)))))

所以我在handlexes中调用load-file。这不起作用 - 主要是。当我运行包含自己的异常处理程序的脚本时,它会工作,如上所述!没有脚本中的异常处理程序,没有。奇怪的。

好吧无论如何,所以我的问题是这里到底发生了什么?

  • 是否真的没有在期货中处理?
  • 为什么在加载文件中发生异常时没有捕获异常?
  • 如何在这种情况下捕捉异常?

1 个答案:

答案 0 :(得分:6)

您似乎没有取消引用(使用deref@)您在示例中生成的未来。

如果在将来抛出异常,尝试取消引用该未来将导致抛出java.util.concurrent.ExecutionException。此异常将包装将来抛出的任何内容。

(try
  (future (/ 10 0))
  "done"
  (catch Exception e
    (str "caught " e)))

;=> "done"


(try
  @(future (/ 10 0))
  "done"
  (catch Exception e
    (str "caught " e)))

;=> "caught java.util.concurrent.ExecutionException: java.lang.ArithmeticException: Divide by zero"