Что проверяет вопрос про CompletableFuture.exceptionally()
exceptionally() перехватывает исключение из предыдущей стадии и возвращает fallback-значение того же типа. Если исходная стадия завершилась без ошибки, exceptionally() просто пропускает её результат дальше без изменений.
Отличие от handle() в том, что exceptionally() не видит успешный результат вообще - в сигнатуре только Throwable, а не пара (result, exception). Если нужно обработать оба случая одной функцией, берут handle() или whenComplete().
Тонкость, которую редко проверяют явно: exceptionally() сам может выбросить исключение внутри лямбды - тогда итоговый future завершится этим новым исключением, а не оригинальным.
CompletableFuture result = CompletableFuture .supplyAsync(() -> { throw new RuntimeException("fail"); }) .exceptionally(ex -> { log.warn("fallback", ex); return -1; });
Что спросят следом: перехватит ли exceptionally() исключение, если он стоит после thenApply(), а сама ошибка произошла ещё в supplyAsync()? Ответ - да, потому что исключение распространяется по цепочке стадий вниз, а не теряется на промежуточном thenApply().
Финал: exceptionally() - это catch для одной ветки, не полноценный обработчик обоих исходов.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки