0

我用玩!带有 ReactiveMongo 插件的框架(相应的版本 2.3 和 0.11)。我有下一个代码,它从 MongoDB 集合中删除项目并返回一些受影响的项目:

/**
  * Removes all subscribers by subscription id
  * 
  * @param subscriptionId id of the subscription
  * @return count of removed subscribers
  */  
def deleteAll(subscriptionId: String): Future[Int] = {
      logger.debug(s"Removing all subscribers with subscription id '$subscriptionId'...")
      val query = BSONDocument("subscriptionId" -> BSONObjectID(subscriptionId))
      subscribersCollection.remove(query) map { writeResult: WriteResult =>
        writeResult.n match {
          case subscribersRemoved if subscribersRemoved > 0 =>
            logger.debug(s"Successfully removed $subscribersRemoved subscribers with subscribtion id '$subscriptionId'")
          case _ => logger.debug(s"No subscribers with subscribtion id '$subscriptionId' were removed")
        }
        writeResult.n
      }
  }

由于 ReactiveMongo 文档,WriteResultcollectionremove()方法返回的类具有诸如hasError和之类的字段,writeErrors用于指示在执行数据库查询期间发生的错误。

WriteResult那么,根据'shasError字段来增强我的方法以从中返回失败的最佳和最干净的方法是什么?

这是一个粗略的例子:

subscribersCollection.remove(query).??? match {
  case Success(writeResult) if writeResult.hasErrors => Failure(new DatabaseException(writeResult.errMsg, writeResult.code)
  case any => any
}

Failure即使数据库查询返回Success带有错误字段的方法,我的方法也应该返回

提前致谢!为了使我的代码更好,我真的很感激任何帮助

PS我考虑过将我所有的代码都包装进去,只是在标志设置为时Try抛出一个异常,但我相信它可以以更好的方式完成,也许使用's方法hasErrortrueFuturetransform()

PPS 由于某些原因,来自 ReactiveMongo文档的代码示例和演示不处理WriteError' 的错误字段和标志。事实上,文件说

如果写入结果确实指示错误,Future 将处于失败状态

但是,我已经在几个应用程序的生产代码中看到了这样的处理,所以它有点令人困惑。是不是意味着这种处理过度了?

4

1 回答 1

2

使用flatMapFuture.failed

做上然后根据值flatMap返回FutureFuture.failed(new Exception("unexpected value"))

假设我们有一个函数返回某个 int 的未来

def httpStatus: Future[Int] = Future { 404 }

httpStatus.flatMap { 
 case 404 => //return failed future
  Future.failed(new Exception("Bad status"))
 case value => value
}

现在你的代码变成了

def deleteAll(subscriptionId: String): Future[Int] = {
      logger.debug(s"Removing all subscribers with subscription id '$subscriptionId'...")
      val query = BSONDocument("subscriptionId" -> BSONObjectID(subscriptionId))
      subscribersCollection.remove(query) flatMap { writeResult: WriteResult =>
        writeResult.n match {
          case subscribersRemoved if subscribersRemoved > 0 =>
            logger.debug(s"Successfully removed $subscribersRemoved subscribers with subscribtion id '$subscriptionId'")
            Future.successful(writeResult.n)
          case status => 
             logger.debug(s"No subscribers with subscribtion id '$subscriptionId' were removed")
             Future.failed(new Exception(s"bad status exception. status: $status"))
        }

      }
  }
于 2017-02-09T10:13:29.327 回答