如何通过内部函数将异常返回给Action函数?

时间:2017-02-19 22:44:43

标签: java scala exception-handling future concurrent.futures

我有一个简单的动作功能:

def someActionFunc() = Action.async { request =>

 myService.doSomething1().map { res =>
        logger.debug(res.getMessageId)
        Ok(res.getMessageId)
      }.recover {
        case ex =>
          logger.error(s"fail:", ex)
          BadRequest(s"fail with error: ${ex.getMessage}")
      }
}

doSomething1会返回Future,而在doSomething1我会调用其他函数doSomething2来返回某个对象并且异常发生在那里,但我不知道知道如何将doSomething2doSomething1中发生的错误返回到操作函数(someActionFunc),因为我想要返回用户fail with error: my reason

所以我尝试在doSomething2做类似的事情:

def doSomething2(someCondition: Boolean) = {
      if (someCondition){
        throw new RuntimeException("my reason")
      }
    }

但是我被抛出,如何正确地将错误返回给用户抛出动作函数?

1 个答案:

答案 0 :(得分:2)

在Scala中,Future[T]实际上只是Try[T],需要一些时间才能完成。反过来,Try[T]只能 Success[T]Failure[T] - 其中Failure[T]实际上只是异常的包装。

您的错误处理链无法正常工作的原因是您正在规避Scala的功能处理方式(完全基于来自函数的返回值),而是使用Java风格的{{ 1}} idiom - 当然它仍然适用于JVM,但不是Scala惯用的。

如果你像这样重写throw

doSomething2

您将获得正在寻找的惯用Scala错误处理。

有些注意事项:

  • 我使用Future 对象上的def doSomething2(someCondition: Boolean):Future[Int] = { if (someCondition){ Future.failed(new RuntimeException("my reason")) } else { Future.succesful(42) } } failed()方法,方便地构建围绕我可能结果的必要包装
  • 虽然我创建 successful()个实例,但从不 Exception
  • 我已明确声明throw的返回类型,以帮助编译器确保正确性 - 之前doSomething2的返回类型是什么? doSomething2