我有这个功能使用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
值会触发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
来处理将来执行中的最终问题,这将使这段代码更加难以辨认。
答案 0 :(得分:3)
Try
是你的朋友。
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
中的错误消息替换所有异常。尽管如此,我们可能会更精细一些。也许我们可以将无效网址保持为成功Future[String]
,但将所有其他网址转换为失败的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{ .. }
。