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.
JavaScript try and catchThe try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.
catch statement is comprised of a try block and either a catch block, a finally block, or both. The code in the try block is executed first, and if it throws an exception, the code in the catch block will be executed. The code in the finally block will always be executed before control flow exits the entire construct.
To catch specific exceptions, the on keyword can be used instead of catch . The catch block can be left at the bottom to catch other exceptions. The finally block is optional and is always executed whether any exception is thrown or not. It is executed after the try/on/catch blocks.
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))
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With