CompletableFuture针对异常场景的thenAccept等效实现方案
实现方案
核心思路
JDK自带的CompletionStage没有直接提供仅消费异常的Consumer类API,我们可以基于exceptionally封装工具方法,在保证不改变原异步执行链路结果的前提下,满足仅消费异常的需求。
封装实现代码
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.function.Consumer; public class CompletionStageUtils { /** * 仅处理CompletionStage的异常场景,入参为仅接收Throwable的Consumer * @param stage 原始异步任务实例 * @param exceptionConsumer 异常消费逻辑 * @return 处理后的CompletionStage,结果和原链路保持一致(不会吞异常) */ public static <T> CompletionStage<T> exceptionallyAccept(CompletionStage<T> stage, Consumer<Throwable> exceptionConsumer) { return stage.exceptionally(ex -> { // 执行自定义的异常消费逻辑 exceptionConsumer.accept(ex); // 重新抛出原异常,保证后续链路能拿到和原任务一致的结果 throw new CompletionException(ex); }); } }
使用示例
// 模拟抛出异常的异步任务 CompletionStage<String> task = CompletableFuture.supplyAsync(() -> { throw new IllegalArgumentException("业务参数非法"); }); // 仅处理异常,不需要写返回值,用法和thenAccept处理正常结果完全对应 CompletionStageUtils.exceptionallyAccept(task, ex -> { System.err.println("异步任务执行出错:" + ex.getMessage()); });
注意事项
- 如果你处理完异常后不需要继续向下传递异常,而是要返回默认值,只需要把工具方法中
throw new CompletionException(ex)的逻辑替换为返回对应类型的默认值即可,比如return null;或者业务定义的默认返回值 - 该实现和
whenComplete的核心区别是:不需要你自行判断异常是否为null,仅在异常场景下才会触发你传入的消费逻辑,完全匹配你需要的「类似thenAccept处理成功场景的异常专属Consumer」需求
内容的提问来源于stack exchange,提问作者andresp
相关产品推荐
相关产品推荐

