Dean Hiller
Dean Hiller

Reputation: 20182

How to translate exception to another using futures in addition to map and flatMap

We currently have code like this

def somemethod() : Future[Resp] = {
   val responseFuture = service.serveV2(req)
   val nextFuture = responseFuture flatMap {
       //do something on success including call to next async service
   }
   nextFuture
}

Of course, the map is being skipped on a timeout but I need to translate that timeout into a proper exception that I can pass up to our web framework to return the correct response code. How does one do this in scala?

Also of note is that I need to return that future. Maybe I should be creating a promise and wiring in responseFuture.onFailure into that promise or am I completely off base here? (I am wondering if there is an easier way or I could try to go down that path).

Upvotes: 1

Views: 221

Answers (1)

cmbaxter
cmbaxter

Reputation: 35443

You might want to take a look at recoverWith as it allows you to turn a Throwable into another Future that can either be a failure or a success, depending on how you want to handle it. This is a bit more flexible than regular recover in that you don't always have to return a successful result in your transformation. So you could do something like this:

val newFuture = fut.flatMap(doSomething).recoverWith{
  case t:TimeoutException => Future.failed(new SomeOtherException("timeout!!!"))
}

If we get a successful future, the flatMap will take effect and the recoverWith won't do anything as it's partial function won't match. If the future is failed with a non-TimeoutException when the flatMap won't happen and the recoverWith won't do anything either as the PF won't match. If it fails due to a TimeoutException then the flatMap won't happen and the recoverWith will kick in and turn it into a failed future wrapping a new SomeOtherException

Upvotes: 6

Related Questions