web-dev-qa-db-ja.com

ClojurescriptでJavascript例外をキャッチする方法は?

私の通信レイヤーでは、JavaScriptの例外をキャッチし、ログに記録して、通常どおりに続行できるようにする必要があります。 Clojurescriptで例外をキャッチするための現在の構文では、キャッチされる例外のタイプを指定する必要があります。

キャッチフォームでnil、js/Error、js/objectを使用しようとしましたが、javascript例外(オブジェクトのタイプとして文字列を持つことができます)をキャッチしません。

これをClojurescriptでネイティブに実行する方法についてのヒントをいただければ幸いです。

23
Dima B.

David Nolenで別の可能な答えを見つけました "Light Table ClojureScriptチュートリアル"

;; Error Handling
;; ============================================================================

;; Error handling in ClojureScript is relatively straightforward and more or
;; less similar to what is offered in JavaScript.

;; You can construct an error like this.

(js/Error. "Oops")

;; You can throw an error like this.

(throw (js/Error. "Oops"))

;; You can catch an error like this.

(try
  (throw (js/Error. "Oops"))
  (catch js/Error e
    e))

;; JavaScript unfortunately allows you to throw anything. You can handle
;; this in ClojureScript with the following.

(try
  (throw (js/Error. "Oops"))
  (catch :default e
    e))
48
tangrammer

Js/Objectがそれらすべてをキャッチしているようです( https://himera.herokuapp.com でテスト済み):

cljs.user> (try (throw (js/Error. "some error")) (catch js/Object e (str "Caught: " e)))
"Caught: Error: some error"
cljs.user> (try (throw "string error") (catch js/Object e (str "Caught: " e)))
"Caught: string error"
cljs.user> (try (js/eval "throw 'js error';") (catch js/Object e (str "Caught: " e)))
"Caught: js error"

注意すべきことの1つは、怠惰なシーケンスです。遅延シーケンスでエラーがスローされた場合、try関数を終了するまで、コードのその部分が実行されない可能性があります。例えば:

cljs.user> (try (map #(if (zero? %) (throw "some error")) [1]))
(nil)
cljs.user> (try (map #(if (zero? %) (throw "some error")) [0]))
; script fails with "Uncaught some error"

最後のケースでは、mapは遅延シーケンスを作成し、try関数はそれを返します。次に、replがシーケンスをコンソールに出力しようとすると、シーケンスが評価され、try式の外部でエラーがスローされます。

5
bmaddy

このリンクで解決策を見つけたと思います https://groups.google.com/forum/#!topic/clojure/QHaTwjD4zz

ここに内容をコピーします:このソリューションはHerwigHochleitnerによって公開されました

try in clojurescriptは、実際には組み込みのtry *を使用し、タイプディスパッチを追加するマクロです。したがって、すべてをキャッチするには、(try * ...(catch e ...))を使用します。これは、javascriptの試行に直接マップされます。

そして、これが私の実装が現在機能していることです:

(defn is-dir? [the_dir]
  (try*
    (if-let [stat (.statSync fs the_dir )]
      (.isDirectory stat)
      false)
    (catch  e 
      (println "catching all exceptions, include js/exeptions")
      false
      )
    )
  )

お役に立てば幸いです
ファン

4
tangrammer