Dean Hiller
Dean Hiller

Reputation: 20190

java completable futures and exception chaining

I have the following code

    return future.exceptionally(t -> {
        if(t instanceof NotFoundException)
            return processNotFound(responseCb, requestCtx, (NotFoundException) t, errorRoutes, null);

        throw new CompletionException(t.getMessage(), t);
        //in scala we would return new CompletableFuture.completeExceptionally(t) and not throw
    });

where processNotFound returns a CompletableFuture as well that could have failed.

Basically, these steps 1. hit primary system 2. catch exception for recovery 3. return future of recovery that may have failed or succeeded

I know how to do this in scala but am not sure how to do this in java. anyone know?

Upvotes: 0

Views: 809

Answers (2)

Kunal Grover
Kunal Grover

Reputation: 300

Yes Java 8 doesn't have Maybe inbuilt, but it should be pretty simple to add(similar to your answer above). Here's a library that does it: https://github.com/npryce/maybe-java

But if you just want to return a CompletableFuture, you can try using .thenCompose() method. Here's an example:

CompletableFuture<Integer> getCompletableFuture(CompletableFuture<Integer> future) {
    return future.handle((r, ex) -> {
        CompletableFuture<Integer> res = new CompletableFuture<>();
        if (ex != null) {
            res.complete(r);
        } else {
            res.completeExceptionally(ex);
        }
        return res;
    }).thenCompose(cf -> cf);
}

Upvotes: 1

Dean Hiller
Dean Hiller

Reputation: 20190

Well, I came up with my own solution which is a hack

public static <T> ExceptionOrResult<T> convert(Throwable t, T res) {
    return new ExceptionOrResult<T>(t, res);
}

/**
 * This sucks as I could not find a way to compose failures in java(in scala they have a function for this)
 */
public static <T> CompletableFuture<T> composeFailure(CompletableFuture<T> future, Function<Throwable, CompletableFuture<T>> exceptionally) {
    return future.handle((r, t) -> convert(t, r)).thenCompose((r) -> {
        if(r.getException() == null)
            return CompletableFuture.completedFuture(r.getResult());
        return exceptionally.apply(r.getException());
    });
}

Upvotes: 2

Related Questions