Scala 无法处理来自未来故障的异常
我希望下面的代码在方法之一,Scala 无法处理来自未来故障的异常,scala,exception-handling,playframework-2.0,future,Scala,Exception Handling,Playframework 2.0,Future,我希望下面的代码在方法之一,callfuture1()或callfuture2()引发异常时返回自定义消息。我的理解是,如果未来的任何一个失败,f都将是失败的未来 但是,当callfuture1抛出异常时f.ON故障未执行。相反,我看到调用堆栈停止在callFuture1()中的代码行,在那里发生异常并返回标准内部错误。为什么会这样 val f = for { x <- callfuture1() y <- callfuture2() } yield y f.onFailure
callfuture1()
或callfuture2()
引发异常时返回自定义消息。我的理解是,如果未来的任何一个失败,f
都将是失败的未来
但是,当callfuture1
抛出异常时<代码>f.ON故障未执行。相反,我看到调用堆栈停止在callFuture1()
中的代码行,在那里发生异常并返回标准内部错误。为什么会这样
val f = for {
x <- callfuture1()
y <- callfuture2()
} yield y
f.onFailure {
//send an internalserver error with some custom message
}
f.map {
//send data back
}
val f=for{
x在callfuture1()
中,您似乎没有像这样将所有进程包装在未来构造函数中
def callfuture1():Future[?]=Future{
val x=。。。
x
}
但你的代码似乎是
def callfuture1():Future[?]={
val x=…//这里发生了一些错误
未来(x)
}
因此,因为它在未来之外,所以您的错误会直接抛出到程序代码中如果callfuture1
抛出“未来之外”,则可能会发生这种情况。
你的理解力被分解为:
val f = callfuture1.flatMap{ x =>
callfuture2.map{ y =>
y
}
}
如果callfuture2
立即抛出(与返回失败的未来相反),您仍然会以失败的未来告终,因为callfuture2
在future.flatMap
中调用,它捕获异常并将其转化为失败的未来(与future.map
相同)
对于callfuture1
,情况就不同了:如果它立即抛出,就没有封闭的Future.map
或Future.flatMap
将它变成失败的未来
一般来说,您应该尽量避免使用返回未来
并且可能抛出错误的方法。
这意味着,如果callfuture1
执行任何可能抛出的操作,它应该捕获该操作,并在失败的将来引发异常,然后返回该异常
更新:关于您对如何返回“狗屎发生了,但我还可以”的预期的更新:
正如Dima在评论中已经暗示的那样,Future.onFailure
只能用于副作用。未来是不可变的。如果您想从失败的异常中恢复,则无法修改原始(失败的)未来,您实际上所能做的就是将其转换为新的未来。
看一看。它正是你所需要的,也就是说,它允许通过匹配失败的结果(如果有的话)并将其转换为成功的未来来转换输入未来。它相当于catch子句,但用于未来。具体来说,你真正想做的是这样的:
def controllerfunction(id: String) = Action.async{
val f = for{
x <- callfuture1(id)
y <- callfuture2(x)
} yield y
f.map{ resp: String =>
Ok(resp)
}.recover{
case t: Throwable =>
println("This gets printed");
Ok("shit happened, but i am still ok")
}
}
def controllerfunction(id:String)=Action.async{
val f=用于{
x
println(“这被打印”);
好(“大便发生了,但我还是好的”)
}
}
Tryval f1=callfuture1();val f2=callfuture2;f=对于{x,“堆栈停止”是什么意思?什么是“标准内部错误”?您如何知道onFailure
未执行?实际错误是什么?还有。请注意onFailure
只能用于副作用。它不能更改未来中包含的异常。如果您想处理异常,您需要使用转换或恢复答案不是place提问,使用评论我知道,但我现在没有足够的声誉我更新了问题。我解决了异常被抛出到未来之外的问题,但我仍然看到我无法解释的行为:(.有什么见解吗?
def controllerfunction(id: String) = Action.async{
val f = for{
x <- callfuture1(id)
y <- callfuture2(x)
} yield y
f.map{ resp: String =>
Ok(resp)
}.recover{
case t: Throwable =>
println("This gets printed");
Ok("shit happened, but i am still ok")
}
}