Hello, Freakin world!

[vavr] try..catch를 함수형 인터페이스 Try로 처리 본문

프로그래밍 언어/Java

[vavr] try..catch를 함수형 인터페이스 Try로 처리

johnna_endure 2021. 3. 9. 16:08

아래와 같은 서비스가 있다고 가정하자.

public class HelloService {
    public String hello() throws Exception {
        throw new Exception("hello exception!");
    }
}

 

hello 메서드는 체크된 예외를 던지기 때문에 hello를 사용하려면 try..catch로 해당 예외를 처리해야된다.

    public void conventionalTry() {
        HelloService service = new HelloService();
        try {
            service.hello();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

이 방법은 코드를 읽을 때 흐름을 방해해 가독성을 떨어뜨린다.

 

vavr 라이브러리에서 제공하는 Try를 사용하면 함수형 인터페이스를 통해 꽤 멋지게 해결할 수 있다.

    public void useVavr() {
        HelloService service = new HelloService();
        Try<String> result = Try.of(service::hello);

        Try<String> recover = result.recover(ex -> Match(ex).of(
                Case($(instanceOf(Exception.class)), "recovered"),
                Case($(), "default")
        ));
        
        System.out.println(recover.isSuccess());
        System.out.println(recover.get());
    }

 

service.hello()의 호출을 람다를 이용해 Try에 넘겨주고, 다시 Try<String> 타입을 반환받았다.

이는 자바의 Optional과 비슷하다. 호출에 성공할 경우 Try는 Success 타입이 되고, 예외로 실패하는 경우 Failure 타입이 된다.

Success와 Failure는 Try의 하위 타입이다.

 

반환받은 Try 인스턴스를 이용해 다시 recover 메서드를 호출해서 Failure를 Success로 바꿀 수도 있다.

recover할 대상을 정하는 조건은 던져진 예외의 타입을 위처럼 정확히 비교해서 하거나 Predicate를 작성해 이용할 수 있다.

 

위에서는 vavr에서 제공하는 패턴 매칭을 이용해서 Exception.class 타입의 경우 회복되도록 했다.

(Exception.class 타입을 매칭하는게 의미있는 방식은 아니지만...)

 

 

resilience4j 공식 문서를 읽어보다가 처음 코드를 보고 vavr 가이드를 좀 읽어봤는데 신박하다.

꽤 자주 사용할 듯.

Comments