I keep seeing this macro <?, in swanodette's code which looks really useful :
In this gist :
;; BOOM!!! we can convert async errors into exceptions
(go (try
(let [x (<? (run-task (.-readFile fs) "foo.txt" "utf8"))]
(.log js/console "Success" x))
(catch js/Error e
(.log js/console "Oops" e))))
In this blog post :
(go (try
(let [tweets (<? (get-tweets-for "swannodette"))
first-url (<? (expand-url (first (parse-urls tweets))))
response (<? (http-get first-url))]
(. js/console (log "Most recent link text:" response)))
(catch js/Error e
(. js/console (error "Error with the twitterverse:" e)))))
<?is just a touch of macro sugar that expands into something like (throw-err (<![expr])). In core.async<!serves the same purpose as ES6's yield operator. If an asynchronous process writes an error onto its channel we will convert it into an exception.
But I can't find a definition for it. How is it implemented in Clojure{Script} ?
Alright so here is what I am using so far. There is probably room for improvement.
In Clojure :
(defn throw-err [e]
(when (instance? Throwable e) (throw e))
e)
(defmacro <? [ch]
`(throw-err (<! ~ch)))
In ClojureScript :
(defn error? [x]
(instance? js/Error x))
(defn throw-err [e]
(when (error? e) (throw e))
e)
(defmacro <? [ch]
`(throw-err (<! ~ch)))
I am completely unsure about the readability of my solution though (throw-err looks like it should throw an error, but it doesn't. At least not every time).
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