Scala-播放:如何很好地处理WS获取异常

End*_*Neu 4 web-services scala http playframework

我有使用Play WS服务的以下功能:

def executeRequest(urls: List[Url]): List[Future[String]] = 
  urls.map(url => {
      WS.url(url.url).get().map(x => url.url + ": " + x.statusText )
  })
Run Code Online (Sandbox Code Playgroud)

Url这样定义的案例类在哪里:

case class Url(id: Long, url: String)
Run Code Online (Sandbox Code Playgroud)

我希望我的应用程序具有弹性,如果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"
    })
  })
Run Code Online (Sandbox Code Playgroud)

这是行不通的,很可能是因为异常是在.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."
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)

这行得通,但是我想以更好,更惯用的方式处理此异常。请注意,这里我没有添加recover来处理将来执行中的最终问题,这将使这段代码更加难以辨认。

Mic*_*jac 5

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."))
)
Run Code Online (Sandbox Code Playgroud)

这会将所有异常替换为中的错误消息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
)
Run Code Online (Sandbox Code Playgroud)

另请注意,future{ .. }不赞成使用。