0

我使用Play!帶有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文檔中,通過收集的remove()方法返回WriteResult類具有諸如hasErrorwriteErrors指示的錯誤,發生在執行數據庫查詢期間。

那麼根據WriteResulthasError這個字段,什麼是最好最乾淨的方法來增強我的方法以返回失敗呢?

這裏是粗略的例子:

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

即即使數據庫查詢返回帶有錯誤字段的Success,我的方法應返回Failure

在此先感謝!我真的很感謝任何幫助,以使我的代碼更好

P.S.我已經考慮包裹我的所有代碼Try,只是投擲hasError標誌設置爲true一個例外,但我認爲,它可以以更好的方式與Futuretransform()方法

P.P.S.來完成,也許由於某些原因,來自ReactiveMongo documentation的代碼示例和演示不處理WriteError的錯誤字段和標誌。事實上,文件說,

如果寫結果實際上表明一個錯誤,未來將在 故障狀態

不過,我已經看到在生產代碼,這樣處理幾個應用程序,所以它有點混亂。這是否意味着這種處理過度?

+0

ReactiveMongo 0.11現在已經過時了。 WriteResult的處理記錄爲新版本:http://reactivemongo.org/releases/0.12/documentation/tutorial/write-documents.html – cchantep

+0

謝謝。遷移是在計劃中,但現在是否意味着「無需檢查WriteResult.ok」對於0.11的WriteResult是否可用? –

+0

如果存在致命的MongoDB錯誤/失敗,則不能成功執行'Future [WriteResult] – cchantep

回答

2

使用flatMapFuture.failed

做的Future然後flatMap基於價值迴歸Future.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")) 
     } 

     } 
    }