How to get stacktraces from bugs in clojure futures?

I have several tasks that are completely independent, and I highlighted futures. These tasks pass certain events back to the main application via core.async / chan or just talk to db.

Some of these futures are now failing. I don't get any stacks in my logs or on std {out, err}. I tried to surround the code in fns caused by futures with

(try (do-stuff)
  (catch Exception e
    (log/error e))

just to get some output in my magazines, but this is amazing! - does not work.

Is my only way to deploy another thread that does the following in a loop?

(let [m (Thread/getAllStackTraces)]
    (doseq [e (.entrySet m)]
      (log/error (.toString (.getKey e)))
      (doseq [s (.getValue e)]
        (log/error " " (.toString s)))))

, , ? , - ?

+4
2

Java Future. , , . , Future . ExecutionException, . deref Clojure.

, -:

(defn die [] (throw (RuntimeException.)))

, :

user=> (def x (future (die)))
#'user/x
; Note: No exception here
user=> @x
RuntimeException   user/die (NO_SOURCE_FILE:1)
; Bam! Exception thrown on deref, think of it as
; ExecutionException when getting failed future value in Java

, deref:

user=> (def x (future (die)))
#'user/x
(try @x (catch Exception e (println "Caught ya")))
Caught ya
nil

:

user=> (def x 
  #_=>   (future 
  #_=>     (try (die)
  #_=>       (catch Exception e
  #_=>         (print "Caught ya!")
  #_=>         "Something"))))
#'user/x
Caught ya
user=> @x
"Something"

, "Caught ya" , , deref. deref , catch .

, - ​​ , Java-.

+5

Stuart Sierra . , . , , :

;; Assuming require [clojure.tools.logging :as log]
(Thread/setDefaultUncaughtExceptionHandler
  (reify Thread$UncaughtExceptionHandler
    (uncaughtException [_ thread ex]
      (log/error ex "Uncaught exception on" (.getName thread)))))
0

Source: https://habr.com/ru/post/1547826/


All Articles