我有一个简单的动作功能:
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
来返回某个对象并且异常发生在那里,但我不知道知道如何将doSomething2
到doSomething1
中发生的错误返回到操作函数(someActionFunc
),因为我想要返回用户fail with error: my reason
所以我尝试在doSomething2
做类似的事情:
def doSomething2(someCondition: Boolean) = {
if (someCondition){
throw new RuntimeException("my reason")
}
}
但是我被抛出,如何正确地将错误返回给用户抛出动作函数?
答案 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
?