Наше приложение имеет некоторый код, который работает асинхронно и не работает. Как это:
CompletableFuture.runAsync(
() -> { throw new RuntimeException("bad"); },
executorService
);
Нам нужен код обработки исключений по умолчанию, который может отлавливать эти ошибки, в случае, если конкретные пользователи забывают обрабатывать исключения (это произошло из-за рабочей ошибки).
Это очевидно сложно. Ответ, данный в Обработка исключений из задач Java ExecutorService не работает.
Он полагается на задачу, являющуюся Future<?>
, а затем вызывающую get()
, в результате чего исключение выдается снова. Но это не относится к runAsync
коду.
runAsync
создает класс java.util.concurrent.CompletableFuture.AsyncRun
, который пытается подавить все исключения. Несмотря на то, что он сам по себе Future
, он не указывает на то, что он isDone()
, и, похоже, не предоставляет способа извлечь из него исключения.
Итак, учитывая следующий пример, как мы должны ловить эти грубые исключения?
Обратите внимание, что мы действительно хотим что-то, что будет перехватывать все необработанные исключения в runAsync
коде, а не то, что мы можем добавить к каждому runAsync
вызову. Просто слишком легко забыть добавить код обработки к каждому из них.
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException {
ExecutorService executorService = new ThreadPoolExecutor(
1, 1, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()
) {
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
// TODO: Magically extract the exception from `r`
}
};
CompletableFuture.runAsync(
() -> { throw new RuntimeException("bad"); },
executorService
);
}
}