Futures don't quite work like this. The exception does not escape.
(deref (future (do (Thread/sleep 100) (/ 0 0))))
ExecutionException java.lang.ArithmeticException: Divide by zero
java.util.concurrent.FutureTask.report (FutureTask.java:122)
java.util.concurrent.FutureTask.get (FutureTask.java:192)
clojure.core/deref-future (core.clj:2108)
clojure.core/future-call/reify--6267 (core.clj:6308)
clojure.core/deref (core.clj:2128)
At the core of Java's FutureTask.run() is the answer...
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
This saves the problem for the eventual consumer of the future's response. If we reframe the test case slightly, we can clearly see the exception handler work:
(Thread/setDefaultUncaughtExceptionHandler
(proxy [Thread$UncaughtExceptionHandler] []
(uncaughtException [thread throwable]
(do (println "****" (-> throwable .getMessage))
))))
I removed the getCause as we don't necessarily have one...
(.start (Thread. #(/ 0 0)))
Yields on stdout...
**** Divide by zero
If all you are after (as suggested by your comment) is a thread with an appropriate exception handler, have you considered something like the following:
(defn exception-safe-queue-reader [source sink]
(try
(let [message (source)]
(sink message))
(catch Throwable t
(println "****" t))
(recur source sink))
This is (to me) a more standard Java idiom than using the uEH - i.e. if you're going to deal with errors, then deal with them in your code directly. Whether you start it using a bare Java thread or future is irrelevant.