트위터의 Future.rescure 함수가 마음에 들 때가 있다. (간결함이 좋다..)




https://twitter.github.io/util/docs/com/twitter/util/Future.html를 참조하면. 예외가 발생할 때 새로운 결과로 이어지게 한다. 코드가 간결해 진다. 


def rescue[B >: A](rescueException: PartialFunction[Throwable, Future[B]]): Future[B]

If this, the original future, results in an exceptional computation, rescueException may convert the failure into a new result.


import com.twitter.util.{Await, Future}
val f1: Future[Int] = Future.exception(new Exception("boom1!"))
val f2: Future[Int] = Future.exception(new Exception("boom2!"))
val newf: Future[Int] => Future[Int] = x => x.rescue {
	case e: Exception if e.getMessage == "boom1!" => Future.value(1)
}
Await.result(newf(f1)) // 1
Await.result(newf(f2)) // throws java.lang.Exception: boom2!




실제 예.


https://github.com/rodrigodealer/finagle_bootstrap/blob/master/src/main/scala/com/github/rodrigodealer/FacebookService.scala#L25

 def getToken : Future[Option[FacebookToken]] = {

    val request = GetRequest(s"/oauth/access_token?client_id=$apiKey&client_secret=$apiSecret&grant_type=client_credentials",

      "graph.facebook.com", true)

    perform(request) flatMap { token =>

      token.status match {

        case Ok => Future(Option(fromJson[FacebookToken](token.contentString)))

        case _ => Future(Option.empty)

      }

    } rescue { case _ => Future(Option.empty)}

  }



자바의 Future에는 rescue대신 exceptionally가 있다. 예쁘지 않다... 



AtomicBoolean thenAcceptCalled = new AtomicBoolean(false);

        AtomicBoolean exceptionallyCalled = new AtomicBoolean(false);

        CompletableFuture<String> future = new CompletableFuture<>();

        future.thenAccept(value -> {

            thenAcceptCalled.set(true);

        }).exceptionally(throwable -> {

            exceptionallyCalled.set(true);

            return null;

        });

        future.completeExceptionally(new RuntimeException());

        assertThat(thenAcceptCalled.get(), is(false));

        assertThat(exceptionallyCalled.get(), is(true));



Posted by '김용환'
,