Well, the answer is clearly described in scaladocs:
/** Creates a new future that will handle any matching throwable that this
* future might contain. If there is no match, or if this future contains
* a valid result then the new future will contain the same.
*
* Example:
*
* {{{
* Future (6 / 0) recover { case e: ArithmeticException => 0 } // result: 0
* Future (6 / 0) recover { case e: NotFoundException => 0 } // result: exception
* Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3
* }}}
*/
def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = {
/** Creates a new future that will handle any matching throwable that this
* future might contain by assigning it a value of another future.
*
* If there is no match, or if this future contains
* a valid result then the new future will contain the same result.
*
* Example:
*
* {{{
* val f = Future { Int.MaxValue }
* Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue
* }}}
*/
def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = {
recover
wraps plain result in Future
for you (analogue of map
), while recoverWith
expects Future
as the result (analogue of flatMap
).
So, here is rule of thumb:
If you recover with something that already returns Future
, use recoverWith
, otherwise use recover
.
update
In your case, using recover
is preferred, as it wraps the exception in Future
for you. Otherwise there is no performance gain or anything, so you just avoid some boilerplate.
recover
? https://mcmap.net/q/302543/-how-to-transform-failed-future-exceptions-in-scala/14955 – Biggerstaffrecover
is still pretty much the only option, unfortunately, but it's important to understand what you're taking advantage of. – Dresslertransform
to transform the exception. – Ratel