@Async与CompletableFuture#get不会引发自定义RuntimeException

时间:2018-10-23 17:14:06

标签: java spring-boot exception-handling completable-future spring-async

我有这种方法:

@Async
@Override
public CompletableFuture<List<ProductDTO>> dashboard( ) throws GeneralException {

    List<Product> products = newArrayList();

    /*....
    ....*/

    //I want this exception when calling CompletableFuture#get()
    if ( products.isEmpty() ) {
        throw new GeneralException( "user.not-has.product-message",
                "user.not-has.product-title" );
    }

    return CompletableFuture
            .completedFuture( ...) );
}

GeneralException的定义如下:

public class GeneralException extends RuntimeException {...}

问题是,当抛出GeneralException时,当我调用CompletableFuture#get()获取数据或异常时,我有一个java.util.concurrent.ExecutionException而不是我的自定义GeneralException 。 Spring Doc声称:

  

@Async方法具有Future类型的返回值时,很容易   管理在方法执行过程中引发的异常   在get结果上调用Future时会引发此异常。

我在做什么错? 非常感谢

编辑: 这是客户端代码:

public static <T> T retrieveDataFromCompletableFuture( @NotNull CompletableFuture<T> futureData ) {
    T data = null;
    try {
        data = futureData.get();
    } catch ( Exception e ) {
        log.error( "Can't get data ", e );
    }
    return data;
}

还有一个例外:

java.util.concurrent.ExecutionException: org.app.exceptions.GeneralException: user.not-has.product-message
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
.....
Caused by: org.app.exceptions.GeneralException: user.not-has.product-message

为什么我仍然还有java.util.concurrent.ExecutionException

1 个答案:

答案 0 :(得分:0)

尽量不要抛出异常,而要完整地包含异常

@Async
@Override
public CompletableFuture<List<ProductDTO>> dashboard( ) throws GeneralException {

    List<Product> products = newArrayList();

    /*....
    ....*/

    //I want this exception when calling CompletableFuture#get()
    if ( products.isEmpty() ) {
        CompletableFuture<List<ProductDTO>> result = new CompletableFeature<>();
        result.completeExceptionally(new GeneralException("user.not-has.product-message", 
            "user.not-has.product-title"
        );
        return result;
    }

    return CompletableFuture
        .completedFuture( ...) );
}