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);