You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:36:09