Map the Exception of a failed Future

theon picture theon · Aug 15, 2013 · Viewed 23.1k times · Source

What's the cleanest way to map the Exception of a failed Future in scala?

Say I have:

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global

val f = Future { 
  if(math.random < 0.5) 1 else throw new Exception("Oh no") 
}

If the Future succeeds with 1, I'd like to keep that, however if it fails I would like to change the Exception to a different Exception.

The best I could come up with is transform, however that requires me to make a needless function for the success case:

val f2 = f.transform(s => s, cause => new Exception("Something went wrong", cause))

Is there any reason there is no mapFailure(PartialFunction[Throwable,Throwable])?

Answer

Viktor Klang picture Viktor Klang · Aug 15, 2013

There is also:

f recover { case cause => throw new Exception("Something went wrong", cause) }

Since Scala 2.12 you can do:

f transform {
  case s @ Success(_) => s
  case Failure(cause) => Failure(new Exception("Something went wrong", cause))
}

or

f transform { _.transform(Success(_), cause => Failure(new Exception("Something went wrong", cause)))}