我希望我的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。这不起作用 - 主要是。当我运行包含自己的异常处理程序的脚本时,它会工作,如上所述!没有脚本中的异常处理程序,没有。奇怪的。
好吧无论如何,所以我的问题是这里到底发生了什么?
答案 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"