Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try & Catch When Calling supplyAsync

I am new to CompletableFuture, I will like to call a method MetadataLoginUtil::login which can throw an exception. However, the code below is not compiled although I have 'exceptionally' written. It says that I must wrap the MetadataLoginUtil::login' within try & catch.

Please advise. Thanks ahead !

public void run() throws ConnectionException {
    CompletableFuture<Void> mt = CompletableFuture.supplyAsync(MetadataLoginUtil::login)
            .exceptionally(e -> {
                System.out.println(e);
                return null;
            })
            .thenAccept(e -> System.out.println(e));
}
like image 747
sfdcdev Avatar asked Nov 29 '22 09:11

sfdcdev


1 Answers

This is not a deficiency of how CompletableFuture works in general, but of the convenience methods, all using functional interfaces not allowing checked exceptions. You can solve this with an alternative supplyAsync method:

public static <T> CompletableFuture<T> supplyAsync(Callable<T> c) {
    CompletableFuture<T> f=new CompletableFuture<>();
    CompletableFuture.runAsync(() -> {
        try { f.complete(c.call()); } catch(Throwable t) { f.completeExceptionally(t); }
    });
    return f;
}

This is basically doing the same as the original supplyAsync, but allowing checked exceptions. So you can use it right like in your original attempt, only redirecting the initial supplyAsync call.

CompletableFuture<Void> mt = supplyAsync(MetadataLoginUtil::login)
    .exceptionally(e -> { System.out.println(e); return null; } )
    .thenAccept(e -> System.out.println(e));
like image 146
Holger Avatar answered Dec 04 '22 10:12

Holger