我有下面的代码片段,它可以通过HTTP简单地查找一组URL。
def parse(filter: ParserFilter): Task[Seq[HttpBinaryResponse]] = {
import scalaj.http._
// Extracts all HTML body anchor elements into an Option
val browser = new JsoupBrowser {
override def requestSettings(conn: Connection): Connection =
conn.timeout(2000)
}
val hrefs =
browser.get(filter.url) >> elementList("a[href]") >?> attr("href")
val batched = hrefs.distinct.flatten
.filter(_.startsWith("http"))
//.map(toTask)
.map(href =>
Task {
HttpBinaryResponse.asHttpBinaryResponse(href, Http(href).asString)
})
.sliding(30, 30)
.toSeq
.map(chunk => Task.parSequence(chunk))
Task.sequence(batched).map(_.flatten)
}
我有一个Play控制器,我在那里调用这个函数并运行任务,如下所示:
val batches = appBindings.httpService.parse(parserFilter)
batches.runToFuture.materialize.map {
case Success(elems) =>
Ok(Json.prettyPrint(Json.obj(
"baseURL" -> s"${parserFilter.url}",
"Total Elements" -> s"${elems.size}",
"results" -> HttpBinaryResponse.asJson(elems)
))).enableCors
case Failure(err) =>
Ok(Json.obj("status" -> "error", "message" -> s"${err.getMessage}")).enableCors
}
对于一个导致SSLHandshakeException的URL,我会进入Failure(err(case块,但我想得到以下内容:
- 无论错误是什么,我都希望进入成功块,在那里我已经捕获了任何失败URL的错误消息
如何调整我的任务实现以满足我的需求?有什么想法吗?我尝试了onErrorRecoverWith处理程序,但似乎没有任何效果。有什么想法吗?
我成功地完成了以下任务:
def parse(filter: ParserFilter): Task[Seq[HttpBinaryResponse]] = {
import scalaj.http._
// Extracts all HTML body anchor elements into an Option
val browser = new JsoupBrowser {
override def requestSettings(conn: Connection): Connection =
conn.timeout(2000)
}
val hrefs =
browser.get(filter.url) >> elementList("a[href]") >?> attr("href")
val batched = hrefs.distinct.flatten
.filter(_.startsWith("http"))
//.map(toTask)
.map(href =>
Task {
HttpBinaryResponse.asHttpBinaryResponse(href, Http(href).asString)
}.onErrorRecoverWith { case ex: Exception =>
Task.now(
HttpBinaryResponse(
origin = href,
isSuccess = false,
errorMessage = Some(s"${ex.getMessage}")))
})
.sliding(30, 30)
.toSeq
.map(chunk => Task.parSequence(chunk))
Task.sequence(batched).map(_.flatten)
}