6

私の clojure プログラムには、実行できるスクリプトのディレクトリが必要です。これらのスクリプトはそれぞれ、load-file で実行する clojure コードです。これは将来的に発生するため、スクリプトは独自のスレッドで実行されます。

問題は、スクリプトからのエラー メッセージが表示されないことです。スクリプトが失敗した場合、何が問題なのかを知る方法はありません。これは、future のスレッド内に例外処理がないためだと思います。以下のように、例外処理をスクリプトに入れることができます。

;; script code    
(try

(println (/ 10 0))

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

ただし、スクリプト自体で例外処理を行う必要がないように、例外処理をそれよりも 1 つ上のレベルのロード ファイルに配置したいと思います。

(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 内で発生した例外がキャッチされないのはなぜですか?
  • この状況で例外をキャッチするにはどうすればよいですか?
4

1 に答える 1

7

あなたの例で作成している先物を(derefまたはで)逆参照しているようには見えません。@

Future 内で例外がスローされた場合、その Future を逆参照しようとすると、例外がスロー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"
于 2013-04-24T17:59:30.150 に答える