如何在Scala中转换失败的未来异常? [英] How to transform failed future exceptions in Scala?

查看:87
本文介绍了如何在Scala中转换失败的未来异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直使用 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 。但是,从对问题的评论中: Scala恢复或recoverWith

This code snippet transforms a DatabaseException into a BusinessException. However, from a comment in the question: Scala recover or recoverWith


...一般来说, recover和 recoverWith的意义不是简单地将异常从一种类型转换为另一种类型,而是通过从故障中恢复

... generally speaking the point of "recover" and "recoverWith" is not to simply transform your exceptions from one type to another, but to recover from the failure by performing the task in a different way so that you no longer have a failure.

因此,显然我不应该使用恢复来转换异常。转换未来异常/失败的未来的正确方法是什么?

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中转换失败的未来异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆