我有这种方法:

@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

最佳答案

尝试不抛出异常,而是使用异常完成功能

@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( ...) );
}

10-04 17:43