Lassen Sie CompletableFuture ausnahmsweise () eine SupplyAsync () - Ausnahme behandeln
Die Frage ist ziemlich einfach: Ich suche nach einer eleganten Art, sie CompletableFuture#exceptionally
zusammen mit zu verwenden CompletableFuture#supplyAsync
. Das funktioniert nicht:
private void doesNotCompile() {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(() -> throwSomething())
.exceptionally(Throwable::getMessage);
}
private String throwSomething() throws Exception {
throw new Exception();
}
Ich dachte, die Idee dahinter exceptionally()
war genau, Fälle zu behandeln, in denen ein Exception
geworfen wird. Aber wenn ich das mache, funktioniert es:
private void compiles() {
CompletableFuture<String> thisIsFine = CompletableFuture.supplyAsync(() -> {
try {
throwSomething();
return "";
} catch (Exception e) {
throw new RuntimeException(e);
}
}).exceptionally(Throwable::getMessage);
}
Ich könnte damit arbeiten, aber es sieht schrecklich aus und macht es schwieriger, die Dinge zu warten. Gibt es nicht eine Möglichkeit, dies sauber zu halten, ohne dass alles Exception
in etwas umgewandelt werden muss RuntimeException
?
Antworten
Dies ist vielleicht keine sehr beliebte Bibliothek, aber wir verwenden sie (und von Zeit zu Zeit arbeite ich auch dort; allerdings geringfügig) intern: NoException . Es ist wirklich sehr, sehr schön für meinen Geschmack geschrieben. Dies ist nicht das einzige, was es hat, aber es deckt definitiv Ihren Anwendungsfall ab:
Hier ist ein Beispiel:
import com.machinezoo.noexception.Exceptions;
import java.util.concurrent.CompletableFuture;
public class SO64937499 {
public static void main(String[] args) {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(Exceptions.sneak().supplier(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);
}
private static String throwSomething() throws Exception {
throw new Exception();
}
}
Oder Sie können diese selbst erstellen:
final class CheckedSupplier<T> implements Supplier<T> {
private final SupplierThatThrows<T> supplier;
CheckedSupplier(SupplierThatThrows<T> supplier) {
this.supplier = supplier;
}
@Override
public T get() {
try {
return supplier.get();
} catch (Throwable exception) {
throw new RuntimeException(exception);
}
}
}
@FunctionalInterface
interface SupplierThatThrows<T> {
T get() throws Throwable;
}
Und Verwendung:
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(new CheckedSupplier<>(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);