Scala - Play:如何很好地处理WS异常

时间:2014-06-12 13:42:34

标签: web-services scala http playframework

我有这个功能使用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来处理将来执行中的最终问题,这将使这段代码更加难以辨认。

1 个答案:

答案 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{ .. }