在 ReactiveMongo 16.6 中将错误作为 Future[Result] 处理

Handling errors as a Future[Result] in ReactiveMongo 16.6

如何使用 ReactiveMongo (16.6) 在 Result 中输出 mongoDB 错误?我几乎花了一整天的时间查看样本,但到目前为止还没有做到这一点。 documentation returns a Future[Unit] rather than a Future[Result]. And every other example/sample that I can find either is outdated or does not do this; example_1, example2

的错误部分

这是我想做的事情:

  def updateById(collName: String, id: BSONObjectID) = authAction.async(parse.json) { implicit request: Request[JsValue] =>

    val oWriteJso = request.body.asOpt[JsObject]
    lazy val qJso = Json.obj("_id" -> id)

    val res = oWriteJso.map(
      wJso => mongoRepo.update(collName)(qJso, wJso)().recoverWith {
        case WriteResult.Code(11000) => Future.successful(BadRequest("it went bad"))
        case _ => Future.successful(BadRequest("also bad"))
      }
    )

    res

  }

当然,函数签名为recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U],上面的代码会return一个错误,因为它需要return一个Future[WriteResult]。但是我怎样才能将任何错误消息、代码等(来自mongoDB)放入Result

documentation表示如何恢复一个Future[WriteResult]:

.recover {
  case WriteResult.Code(11000) =>
    // if the result is defined with the error code 11000 (duplicate error)
    println("Match the code 11000")

  case WriteResult.Message("Must match this exact message") =>
    println("Match the error message")

  // ...
}

感谢 Future combinators(不是 ReactiveMongo 特有的),它可以用于 Future.

中任何类型的成功值。
def foo[T](future: Future[WriteResult], recoveredValue: => T)(success: WriteResult => T): Future[T] = future.map(success).recover {
  case WriteResult.Code(11000) =>
    // if the result is defined with the error code 11000 (duplicate error)
    recoveredValue

  case WriteResult.Message("Must match this exact message") =>
    recoveredValue

}