How to catch any Javascript exception in Clojurescript?

我们两清 提交于 2019-12-04 15:39:08

问题


In my communication layer I have a need to be able to catch ANY javascript exception, log it down and proceed as I normally would do. Current syntax for catching exceptions in Clojurescript dictates that I need to specify the type of the exception being caught.

I tried to use nil, js/Error, js/object in the catch form and it doesn't catch ANY javascript exception (which can have string as the type of the object).

I would appreciate any hints how this can be done natively in Clojurescript.


回答1:


I found another possible answer in David Nolen "Light Table ClojureScript Tutorial"

;; 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))



回答2:


It looks like js/Object catches them all (tested on 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"

One thing to watch out for is lazy sequences. If an error is thrown in a lazy sequence that part of the code might not be executed until after you've exited the try function. For example:

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"

In that last case, map creates a lazy sequence and the try function returns it. Then, when the repl tries to print the sequence to the console, it's evaluated and the error gets thrown outside of the try expression.




回答3:


I think I've just found the solution in this link https://groups.google.com/forum/#!topic/clojure/QHaTwjD4zzU

I copy the contents here: This solution was published by Herwig Hochleitner

try in clojurescript is actually a macro that uses the builtin try* and adds type dispatch. So to catch everything, just use (try* ... (catch e ...)). This maps directly to javascript's try.

And here is my implementation working now:

(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
      )
    )
  )

I hope it helps you
Juan



来源:https://stackoverflow.com/questions/12655503/how-to-catch-any-javascript-exception-in-clojurescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!