我有这个使用 Play WS services 的函数:
def executeRequest(urls: List[Url]): List[Future[String]] =
urls.map(url => {
WS.url(url.url).get().map(x => url.url + ": " + x.statusText )
})
其中 Url
是这样定义的案例类:
case class Url(id: Long, url: String)
我希望我的应用程序具有弹性,如果 url 格式不正确,有时 url
值会触发 IllegalArgumentException
。我试过的是这样的:
def executeRequest2(urls: List[Url]): List[Future[String]] =
urls.map(url => {
WS.url(url.url).get().map(x => url.url + ": " + x.statusText )
.recover({
case e: IllegalArgumentException => url.url + " is invalid"
})
})
这行不通,很可能是因为异常是在 .get()
中抛出的,而不是在未来的执行中(无论如何这只是一个猜测)。
我最后做的是这样的:
def executeRequest(urls: List[Url]): List[Future[String]] =
urls.map(url => {
try {
WS.url(url.url).get().map(x => x.statusText)
}
catch {
case e: IllegalArgumentException => future {
url.url + " is illegal."
}
}
})
这行得通,但我想要一些更好、更惯用的方法来处理这个异常。请注意,这里我没有添加 recover
来处理 future 执行中的最终问题,这将使这段代码更加难以辨认。
最佳答案
Try
是你的 friend 。
import scala.util.Try
urls.map(url =>
Try(WS.url(url.url).get().map(x => x.statusText))
.getOrElse(Future.successful(url.url + " is illegal."))
)
这将用 getOrElse
中的错误消息替换所有异常。不过,我们可以比这更细粒度。也许我们可以将无效的 URL 保留为成功的 Future[String]
,但将所有其他 URL 转换为失败的 Future
。
urls.map(url =>
Try(WS.url(url.url).get().map(x => x.statusText))
.recover{case e: IllegalArgumentException => Future.successful(url.url + " is illegal.")}
.recover{case t: Throwable => Future.failed(t)}
.get
)
另请注意,不推荐使用 future{ .. }
。
关于web-services - Scala - Play : how to nicely handle WS get exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24186012/