在Scala

时间:2016-10-06 05:57:02

标签: scala

如果未来返回失败的异常,我该如何处理?

方案是我的代码调用getValue(),将结果映射到verifyValue()然后我希望能够处理getValue()的结果为Future.failed(new Exception("message"))的情况。但是当我运行它时,如果getValue()的结果是失败的未来,它只会抛出异常而不是处理异常。

有没有人对我将如何做到这一点有任何建议?

def method(): Future[JsObject] = {
    getValue().flatMap(verifyValue(_))
}

def getValue(): Future[JsObject] = {
    try {
        value1 <- getValue1()
        value2 <- getValue2(value1)
    } yield {
        value2
    }
}

def verifyValue(result: Any): Future[JsObject] = {
  result match {
    case e: Exception =>
      getValue()
    case json: JsObject => Future.successful(json)
  }
}

更新: 我不认为我用原始问题说清楚了,但是我为什么平面化这个值的原因是我不想明确地等待我的代码中的任何期货,因此我不想要使用Future.onComplete {}来解析值。

更新2: 另一件可能不太清楚的事情是,如果它抛出异常,我想调用另一种方法。我不希望它只是处理异常,它将记录异常,然后调用另一个返回值与getValue()类型相同的方法。

3 个答案:

答案 0 :(得分:6)

使用recoverrecoverWith

当将来因异常而失败时,将调用

recover或recoverWith。在恢复块中,您可以提供替代值。

recoverWithrecover不同,需要未来的某些东西

getValue().recover { case th =>
  //based on the exception type do something here
  defaultValue //returning some default value on failure
}

答案 1 :(得分:3)

我最终做的是使用Future.fallbackTo()方法。

def method(): Future[JsObject] = {
    getValue().fallbackTo(method1()).fallbackTo(method2()).fallbackTo(method3())
}

如果第一个getValue()的未来失败,则会调用method1()。如果这也失败了,它将调用method2()等。如果其中一个方法成功,它将返回该值。如果这些方法都不成功,它将从getValue()返回失败的未来。

这个解决方案并不理想,因为如果所有尝试都失败,我最好想要包括所有四个异常,但它至少允许我重试getValue()方法。

答案 2 :(得分:1)

import scala.util.{Success, Failure}

f.onComplete {
  case Success(value) => // do sth with value
  case Failure(error) => // do sth with error
}

您可以在方法()中使用onComplete,另请参阅以下链接以获取其他选项:

http://www.scala-lang.org/api/2.9.3/scala/concurrent/Future.html