我想在我的play scala web应用程序中做错误处理。
我的应用程序与数据库对话以获取一些行,它遵循以下流程。
1.第一次调用db以获取一些数据
1.使用第一次调用中的数据从数据库中获取其他数据
1.使用从最后两次数据库调用接收到的数据形成响应。
下面是我的伪代码。
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
}
上述理解中的每个方法都返回一个future,这些方法的签名如下。
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] {...}
在以下情况下,我应该如何处理错误/故障
- 当callFuture 1无法从数据库提取数据时。我希望返回包含错误消息的相应错误响应。由于callFuture 2仅在callFuture 1之后执行。如果callFuture 1失败/出错,我不希望执行callFuture 2,并希望立即返回错误消息。(callFuture 2和callFuture 3的情况相同)
- 编辑-
我尝试从getResponse()方法返回一个适当的错误响应,当其中一个callFuture失败并且无法继续执行后续futureCalls时。
根据Peter Neyens的回答,我尝试了以下方法,但给了我一个运行时错误。
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
}
型
运行时错误i get
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
2条答案
按热度按时间2w2cym1i1#
您可以使用
Future.recoverWith
函数来定制Future
失败时的异常。这将导致一个稍微丑陋的理解:
请注意,如果您希望添加更多信息而不仅仅是错误消息,您也可以定义自己的异常来代替
Exception
。如果您不希望细粒度控制根据失败的
Future
中的Throwable
设置不同的错误消息(如callFuture1
),您可以使用隐式类来丰富Future
,以设置更简单的自定义错误消息:型
你可以这样使用:
在这两种情况下,直接使用
errorMsg
或recoverWith
,您仍然依赖于Future
,因此如果Future
失败,将不会执行下面的Futures
,您可以直接使用失败的Future
中的错误消息。您没有指定要如何处理错误消息。例如,如果要使用错误消息创建不同的
Response
,则可以使用recoverWith
或recover
。xuo3flqw2#
假设
future1
、future2
和future3
抛出Throwable
异常,分别命名为Future1Exception
、Future2Exception
和Future3Exception
,那么可以从getResponse()
方法返回相应的错误Response
,如下所示:根据文件
Future.recover
创建一个新的future,它将处理该future可能包含的任何匹配的throwable。