Is it possible to access the input to a previous chained .thenCompose() from within the .handle()?
In the following block, I want to reduce the accumulated x if there is an exception.
@Test
public void Test() {
Integer result = testCompletable().join();
assertThat(result.equals(1));
}
public CompletableFuture<Integer> testCompletable() {
CompletableFuture<Integer> result = CompletableFuture.completedFuture(0);
for (int i = 0; i < 2; i ) {
final int j = i;
result = result.thenCompose(x -> {
if (j == 1) {
throw new RuntimeException("Manually planted ex");
}
x = x 1;
return CompletableFuture.completedFuture(x);
}).handle((r, e) -> {
if (e != null) {
x = x -1; // <-- this line doesn't compile, how to access x here?
}
return x;
});
}
return result;
}
I originally had
.handle((r, e) -> {
if (e != null) {
r = r -1; // r is NULL here.
}
return r;
})
CodePudding user response:
Yes, just store the future in a temporary (final
) variable and call join()
on it to retrieve its value:
public CompletableFuture<Integer> testCompletable() {
CompletableFuture<Integer> result = CompletableFuture.completedFuture(0);
for (int i = 0; i < 2; i ) {
final int j = i;
final var oldResult = result;
result = result.thenCompose(x -> {
if (j == 1) {
throw new RuntimeException("Manually planted ex");
}
x = x 1;
return CompletableFuture.completedFuture(x);
}).handle((r, e) -> {
var x = r;
if (e != null) {
// will not block since it’s guaranteed to be resolved – may throw though
x = oldResult.join() - 1;
}
return x;
});
}
return result;
}