我有一个Future [MyType],它是通过线路上的api调用产生的。如果api调用失败,因为发送了错误的数据,它只会引发异常(不是很有帮助,但我无能为力。
所以我想用try / catch检查并返回Future [Option [MyType]],如下所示:
def myfunc(name:String):Future[Option[MyType]] = {
try {
val d:Future[MyType] = apiCall(name) //returns a Future[MyType]
???? Convert d into future(Some(MyType))
} catch {
future(None)
}
}
谢谢你看看
答案 0 :(得分:4)
这实际上取决于抛出异常的确切位置。如果apiCall
在之前抛出异常,则会创建Future
,您可以映射Future
以将值包装在Option
中:
try {
val d: Future[Option[MyType]] = apiCall(name).map{result => Some(result)}
} catch {
case t: Throwable => Future.successful(None)
}
但是我不认为这是解决这个问题的最好方法,因为你实际上失去了关于为什么api调用失败的信息。 Option
通常不是指示发生错误的绝佳解决方案。我认为更好的解决方案是返回包含异常的未来:
try {
val d:Future[MyType] = apiCall(name)
} catch {
case t: Throwable => Future.failed(t)
}
原因是您处理未来的任何代码都必须在未来处理异常,因此这将使您的所有错误处理都集中在一个地方。
如果在 Future
内抛出异常,则在try / catch块中包装apiCall
不会有帮助,因为不会同步抛出异常,因此,您可以使用map
和recover
:
val d: Future[Option[MyType]] = apiCall(name).map{Some(_)}.recover{
case t: Throwable => None
}