scala - 如何在 Scala 中转换失败的 future 异常?

标签 scala exception future

我一直用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) 
}

此代码片段转换了 DatabaseExceptionBusinessException .但是,从问题中的评论:Scala recover or 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.



所以显然我不应该使用 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)
}

哪个输出
Failed to get Entity by ID. Trying by name...
Entity(42,picard)

请注意我们如何尝试首先通过 id 获取实体,然后失败了,我们尝试通过 name .

关于scala - 如何在 Scala 中转换失败的 future 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59099000/

相关文章:

scala - 字谜递归Scala

rust - "explicit lifetime required"在盒装 future 使用引用变量

scala - 通过python脚本在命令行中执行sbt并输出到文件

java - 如何处理 java.net.URL.openConnection() 抛出的 IOException?

c++ - 为什么用新语法 `noexcept` 重写旧的空抛出规范?

c# - .NET 异常的正确使用

scala - 当子actor在未来的onFailure内抛出异常时,Akka主管actor不会处理异常

c++ - 有效 future 与默认构建 future

scala - 如何使用 sbt-native-packager 在 Docker 中使二进制文件可执行?

scala - 如何让用户在 play framework 2 中切换语言