我想在我的play scala Web应用程序中进行错误处理。
我的应用程序与数据库对话以获取一些行,它遵循以下流程。
下面是我的伪代码。
def getResponse(name: String)
(implicit ctxt: ExecutionContext): Future[Response] = {
for {
future1 <- callFuture1(name)
future2 <- callFuture2(future1.data)
future3 <- callFuture3(future1.data, future2.data)
} yield future3
}
以上理解中的每一个方法都返回一个未来,这些方法的签名如下。
private def callFuture1(name: String)
(implicit ctxt: ExecutionContext): Future[SomeType1] {...}
private def callFuture2(keywords: List[String])
(implicit ctxt: ExecutionContext): Future[SomeType2] {...}
private def callFuture3(data: List[SomeType3], counts: List[Int])
(implicit ctxt: ExecutionContext): Future[Response] {...}
在以下情况下,我该如何进行错误/故障处理
--编辑--
当任何一个调用Future失败并且不能继续后续的future调用时,我试图从getResponse()方法返回一个适当的错误响应。
根据彼得·尼扬的回答,我尝试了以下方法,但出现了运行时错误。。
def getResponse(name: String)
(implicit ctxt: ExecutionContext): Future[Response] = {
for {
future1 <- callFuture1(name) recoverWith {
case e:Exception => return Future{Response(Nil,Nil,e.getMessage)}
}
future2 <- callFuture2(future1.data)
future3 <- callFuture3(future1.data, future2.data)
} yield future3
}
我收到运行时错误
ERROR] [08/31/2015 02:09:45.011] [play-akka.actor.default-dispatcher-3] [ActorSystem(play)] Uncaught error from thread [play-akka.actor.default-dispatcher-3] (scala.runtime.NonLocalReturnControl)
[error] a.a.ActorSystemImpl - Uncaught error from thread [play-akka.actor.default-dispatcher-3]
scala.runtime.NonLocalReturnControl: null
假设 future1
、future2
和 future3
会分别引发名为 Future1Exception
、Future2Exception
和 Future3Exception 的
Throwable
异常。然后,您可以从 getResponse()
方法返回相应的错误响应
,如下所示:
def getResponse(name: String)
(implicit ctxt: ExecutionContext): Future[Response] = {
(for {
future1 <- callFuture1(name)
future2 <- callFuture2(future1.data)
future3 <- callFuture3(future1.data, future2.data)
} yield future3).recover {
case e: Future1Exception =>
// build appropriate Response(...)
case e: Future2Exception =>
// build appropriate Response(...)
case e: Future3Exception =>
// build appropriate Response(...)
}
}
根据文档未来.恢复
创建一个新的future,它将处理这个future可能包含的任何匹配throwable。
如果< code>Future失败,您可以使用< code>Future.recoverWith函数来自定义异常。
val failed = Future.failed(new Exception("boom"))
failed recoverWith {
case e: Exception => Future.failed(new Exception("A prettier error message", e)
}
这将导致理解稍微丑陋:
for {
future1 <- callFuture1(name) recoverWith {
case npe: NullPointerException =>
Future.failed(new Exception("how did this happen in Scala ?", npe))
case e: IllegalArgumentException =>
Future.failed(new Exception("better watch what you give me", e))
case t: Throwable =>
Future.failed(new Exception("pretty message A", t))
}
future2 <- callFuture2(future1.data) recoverWith {
case e: Exception => Future.failed(new Exception("pretty message B", e))
}
future3 <- callFuture3(future1.data, future2.data) recoverWith {
case e: Exception => Future.failed(new Exception("pretty message C", e))
}
} yield future3
请注意,如果您想添加除错误消息之外的更多信息,也可以定义自己的异常来代替< code>Exception。
如果您不希望细粒度控制根据失败的未来
中的Throwable
(如callFuture1
)设置不同的错误消息,您可以使用隐式类来丰富将来
,以设置更简单的自定义错误消息:
implicit class ErrorMessageFuture[A](val future: Future[A]) extends AnyVal {
def errorMsg(error: String): Future[A] = future.recoverWith {
case t: Throwable => Future.failed(new Exception(error, t))
}
}
你可以这样使用:
for {
future1 <- callFuture1(name) errorMsg "pretty A"
future2 <- callFuture2(future1.data) errorMsg "pretty B"
future3 <- callFuture3(future1.data, future2.data) errorMsg "pretty C"
} yield future3
在这两种情况下,直接使用 errorMsg
或 recoverWith
,您仍然依赖于 Future
,因此,如果 Future
失败,则不会执行以下 Futures
,您可以直接使用失败的 Future
中的错误消息。
您没有指定要如何处理错误消息。例如,如果要使用错误消息创建其他响应
,则可以使用 recoverWith
或 recover
。
future3 recover { case e: Exception =>
val errorMsg = e.getMessage
InternalServerError(errorMsg)
}
如果 Scala 未来失败,并且没有延续“观察到”该故障(或者唯一的延续使用 map/flatMap 并且在发生故障时不运行),那么错误就不会被发现。我希望至少记录这些错误,以便我可以找到错误。 我使用术语“观察到的错误”,因为在.Net Tasks中,当GC收集Task对象时,有机会捕获“未观察到的任务异常”。同样,使用同步方法,可以记录终止线程的未捕获异常。 在Scala futures中,“
我正在阅读Scala Cookbook(http://shop.oreilly.com/product/0636920026914.do) 有一个与未来使用相关的例子,涉及理解。 到目前为止,我对理解的理解是,当与一个集合一起使用时,它会产生另一个相同类型的集合。例如,如果每个< code>futureX的类型为< code>Future[Int],则以下内容也应为< code>Future[In
问题内容: 当我的discord bot上网时间过长(大约3-4小时)时,会随机出现此错误,但有时该错误发生得更早,有时又更晚。真的很困扰我 问题答案: 我在自己的代码中为这个问题努力了一段时间。主要问题是跟踪是完全无用的, 并且 错误很少发生,以至于使“在终端中运行并等待”是徒劳的任务。最终,我能够弄清楚Discord.js客户端本身正在引发错误- 在我阅读的任何文档中都没有提到此错误,因此我没
我试图创建一个简洁的结构,用于理解基于未来的业务逻辑。下面是一个示例,其中包含一个基于异常处理的工作示例: 然而,这可能被视为一种非功能性或非Scala的处理方式。有更好的方法吗? 请注意,这些错误来自不同的来源——有些在业务级别(“检查所有权”),有些在控制器级别(“授权”),有些在数据库级别(“找不到实体”)。因此,从单一常见错误类型派生它们的方法可能不起作用。
问题内容: 我之前从未遇到过此错误,所以我不确定该怎么做或意味着什么 未处理的异常类型 它在以下代码中发生: 它给了我2个选项“添加抛出声明”和“使用try / catch进行环绕”。 我该怎么办,为什么? 问题答案: 这意味着您要调用的方法已使用指令声明了从类派生的异常。当以这种方式声明一个方法时,您将被迫使用一个块来处理该异常,或者将一个相同的(对于相同的异常或超类型)语句添加到您的方法声明中
错误: 我的前端vue应用程序正在和后端正在我正在请求axios从vue文件到后端的get请求。 这就是我的终点 这个错误的原因是什么?