2014-03-27 48 views
2

我有一个Future [MyType],它是通过api调用通过线路产生的。如果api调用失败,因为发送了错误的数据,它只会抛出一个异常(不是很有帮助,但我可以做的没有什么)将Future [MyType]转换为Future [Option [MyType]]

所以我想用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) 
    } 

} 

感谢您抽空看看

回答

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不同步引发,所以你可以使用maprecover

val d: Future[Option[MyType]] = apiCall(name).map{Some(_)}.recover{ 
    case t: Throwable => None 
} 
+0

伟大的建议,我不知道错误发生在哪里..我会进一步检查。感谢您抽出时间 – saintlyRook

+0

不要抓住'Throwable',而是抓住'NonFatal'。另外,如果apiCall返回一个Future,我不会期望它抛出任何东西,而是返回失败的Future。 – Calavoow

相关问题