问题描述
我一直使用 recover
来转换失败的期货中的异常,类似于
I have always used recover
to transform exceptions in failed futures similar to
def selectFromDatabase(id: Long): Future[Entity] = ???
val entity = selectFromDatabase(id) recover {
case e: DatabaseException =>
logger.error("Failed ...", e)
throw new BusinessException("Failed ...", e)
}
此代码段将 DatabaseException
转换为 BusinessException
。但是,从对问题的评论中:
This code snippet transforms a DatabaseException
into a BusinessException
. However, from a comment in the question: Scala recover or recoverWith
因此,显然我不应该使用恢复
来转换异常。转换未来
异常/失败的未来
的正确方法是什么?
So apparently I am not supposed to use recover
to transform exceptions. What is the correct way to transform Future
exceptions / failed Future
?
推荐答案
由于您只是将一个异常转换为另一个异常,我认为使用 recover
是可以的。当您想尝试解决问题的其他策略时,即希望返回成功的结果时,请使用 recoverWith
。例如,考虑以下 recoverWith
Since you are simply transforming an exception to another exception, I think using recover
is ok. Use recoverWith
when you want to try a different strategy for solving the problem, that is, when you hope to get a successful result back. For example consider the following use of recoverWith
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object futureRecoverWith extends App {
case class Entity(id: Int, name: String)
def selectFromDatabaseById(id: Int): Future[Entity] = Future(throw new RuntimeException("Boom"))
def selectFromDatabaseByName(name: String): Future[Entity] = Future(Entity(42, "picard"))
val entity =
selectFromDatabaseById(42) recoverWith {
case error =>
println("Failed to get Entity by ID. Trying by name...")
selectFromDatabaseByName("picard")
}
entity.map(println)
}
输出
Failed to get Entity by ID. Trying by name...
Entity(42,picard)
请注意我们如何尝试首先通过 id
获取实体,然后失败,我们尝试通过 name
命名。
Note how we attempted to first get the entity by id
, and then failing that, we attempted by name
.
这篇关于如何在Scala中转换失败的未来异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!