根据成功的价值将成功转化为失败的最佳方法
The best way to convert Success into Failure depending on the value of Success
我用玩!带有 ReactiveMongo 插件的框架(相应版本 2.3 和 0.11)。我有下一个代码,它从 MongoDB 集合中删除项目,returns 一些受影响的项目:
/**
* 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 文档,WriteResult
class returned by collection's remove()
method 具有 hasError
和 writeErrors
等字段指示在执行数据库查询期间发生的错误。
那么,为了根据 WriteResult
的 hasError
字段从中 return 失败,增强我的方法的最佳和最干净的方法是什么?
这是粗略的例子:
subscribersCollection.remove(query).??? match {
case Success(writeResult) if writeResult.hasErrors => Failure(new DatabaseException(writeResult.errMsg, writeResult.code)
case any => any
}
即我的方法应该 return a Failure
即使数据库查询 returns a Success
with error fields
提前致谢!我真的很感激任何帮助,以使我的代码更好
P.S。我考虑过将我所有的代码包装在 Try
中,只是在 hasError
标志设置为 true
时抛出异常,但我相信它可以用更好的方式完成,也许 Future
的transform()
方法
P.P.S。由于某些原因,来自 ReactiveMongo documentation 的代码示例和演示不处理 WriteError
的错误字段和标志。事实上,文档说
If the write result actually indicates an error, the Future will be in
a failed state
但是,我已经在几个应用程序的生产代码中看到过这样的处理,所以它有点令人困惑。这样的处理是不是有点过分了?
使用flatMap
和Future.failed
在 Future
上执行 flatMap
然后根据值 return Future.failed(new Exception("unexpected value"))
假设我们有一个函数return是一些 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"))
}
}
}
我用玩!带有 ReactiveMongo 插件的框架(相应版本 2.3 和 0.11)。我有下一个代码,它从 MongoDB 集合中删除项目,returns 一些受影响的项目:
/**
* 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 文档,WriteResult
class returned by collection's remove()
method 具有 hasError
和 writeErrors
等字段指示在执行数据库查询期间发生的错误。
那么,为了根据 WriteResult
的 hasError
字段从中 return 失败,增强我的方法的最佳和最干净的方法是什么?
这是粗略的例子:
subscribersCollection.remove(query).??? match {
case Success(writeResult) if writeResult.hasErrors => Failure(new DatabaseException(writeResult.errMsg, writeResult.code)
case any => any
}
即我的方法应该 return a Failure
即使数据库查询 returns a Success
with error fields
提前致谢!我真的很感激任何帮助,以使我的代码更好
P.S。我考虑过将我所有的代码包装在 Try
中,只是在 hasError
标志设置为 true
时抛出异常,但我相信它可以用更好的方式完成,也许 Future
的transform()
方法
P.P.S。由于某些原因,来自 ReactiveMongo documentation 的代码示例和演示不处理 WriteError
的错误字段和标志。事实上,文档说
If the write result actually indicates an error, the Future will be in a failed state
但是,我已经在几个应用程序的生产代码中看到过这样的处理,所以它有点令人困惑。这样的处理是不是有点过分了?
使用flatMap
和Future.failed
在 Future
上执行 flatMap
然后根据值 return Future.failed(new Exception("unexpected value"))
假设我们有一个函数return是一些 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"))
}
}
}