kri*_*ath 6 scala future exception
我一直习惯于recover在失败的 future 中转换异常,类似于
def selectFromDatabase(id: Long): Future[Entity] = ???
val entity = selectFromDatabase(id) recover {
case e: DatabaseException =>
logger.error("Failed ...", e)
throw new BusinessException("Failed ...", e)
}
Run Code Online (Sandbox Code Playgroud)
此代码片段将 a 转换DatabaseException为BusinessException. 但是,从问题中的评论来看:Scala恢复或recoverWith
...一般来说,“recover”和“recoverWith”的要点不是简单地将异常从一种类型转换为另一种类型,而是通过以不同的方式执行任务来从故障中恢复,以便不再出现故障。
所以显然我不应该使用recover来转换异常。Future转换异常/失败的正确方法是什么Future?
由于您只是将一个异常转换为另一个异常,所以我认为使用recover是可以的。recoverWith当您想要尝试不同的策略来解决问题时,即当您希望获得成功的结果时使用。例如考虑以下使用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)
}
Run Code Online (Sandbox Code Playgroud)
哪个输出
Failed to get Entity by ID. Trying by name...
Entity(42,picard)
Run Code Online (Sandbox Code Playgroud)
请注意我们如何尝试首先通过 获取实体id,然后如果失败,我们又尝试通过name。