У меня несколько раз был случай, когда исключение в фьючерсах было трудно отследить (и я уже задавал здесь вопрос о том, почему какое-то исключение никогда не происходило, и этот вопрос не является обманом моего старого вопроса) и решил попытаться установить «обработчик необработанных исключений по умолчанию».
Однако я не могу заставить его работать. Я пытался использовать reify и пробовал использовать прокси. Как будто ничего не происходит.
Вот минимальный случай, воспроизводящий проблему:
REPL> (Thread/setDefaultUncaughtExceptionHandler
(proxy [Thread$UncaughtExceptionHandler] []
(uncaughtException [thread throwable]
(do (println (-> throwable .getCause .getMessage))
; (error "whatever...") ; some 'timbre' logging if you have timbre
))))
nil
REPL> (future (do (Thread/sleep 100) (/ 0 0)))
#<core$future_call$reify__6267@c2909a1: :pending>
REPL>
Пробовал println, пробовал логировать в файл с помощью timbre, пробовал плевать во временный файл, пробовал принудительно запускать future с помощью дерефинга... Видимо, неперехваченное исключение по умолчанию обработчик никогда не вызывается.
Может ли кто-нибудь показать мне пример интерактивного/REPL рабочего обработчика необработанных исключений по умолчанию, который фактически перехватывает исключение?
В качестве бонуса вопрос: как только установлен обработчик необработанных исключений по умолчанию, есть ли простой способ «увидеть», что он установлен? И что происходит в REPL, когда вы тестируете эту функцию и несколько раз вызываете setDefaultUncaughtExceptionHandler? Учитывается только последний обработчик?