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(“这被打印”);
好(“大便发生了,但我还是好的”)
}
}

Try
val 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")
  }
}