CompletableFuture 예외적으로 () supplyAsync () 예외 처리
Nov 20 2020
질문은 다소 간단합니다. CompletableFuture#exceptionally
와 함께 사용하는 우아한 방법을 찾고 CompletableFuture#supplyAsync
있습니다. 이것은 작동하지 않는 것입니다.
private void doesNotCompile() {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(() -> throwSomething())
.exceptionally(Throwable::getMessage);
}
private String throwSomething() throws Exception {
throw new Exception();
}
나는이면 exceptionally()
에 있는 아이디어 가 정확하게 Exception
던져지는 경우를 처리 하는 것이라고 생각했습니다 . 그러나 이렇게하면 작동합니다.
private void compiles() {
CompletableFuture<String> thisIsFine = CompletableFuture.supplyAsync(() -> {
try {
throwSomething();
return "";
} catch (Exception e) {
throw new RuntimeException(e);
}
}).exceptionally(Throwable::getMessage);
}
나는 그것으로 일할 수 있지만 끔찍해 보이고 유지하기가 더 어려워졌습니다. 모든 변환이 필요하지 않는이 깨끗하게 유지하는 방법이 아닌가요 Exception
로는 RuntimeException
?
답변
2 Eugene Nov 21 2020 at 02:21
이것은 매우 인기있는 라이브러리가 아닐 수도 있지만 내부적으로 사용합니다 (그리고 때때로 저도 거기에서 약간의 작업을합니다. 사소하지만) : NoException . 제 취향에 맞게 정말 멋지게 쓰여졌습니다. 이것이 유일한 것은 아니지만 사용 사례를 확실히 다룹니다.
다음은 샘플입니다.
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();
}
}
또는 직접 만들 수 있습니다.
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;
}
그리고 사용법 :
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(new CheckedSupplier<>(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);