ReactiveMongo / Play:`LastError:DatabaseException ['<none>']`,而db仍然更新

时间:2016-12-06 23:08:26

标签: mongodb scala reactivemongo

奇怪的问题:虽然我的播放应用程序尝试在使用reactivemongo时插入/更新某些mongoDB集合中的记录,但操作似乎失败并显示一条神秘的消息,但实际上,该记录会插入/更新。

更多信息:

  1. 从mongo控制台插入有问题的集合效果很好
  2. 从所有藏品中读取效果很好
  3. 读取和写入同一数据库中的其他集合效果很好
  4. 写信给曾经工作过的有问题的馆藏。
  5. 错误信息是:

    play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[LastError: DatabaseException['<none>']]]
      at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
      at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
      at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
      at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
      at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
      at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
      at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
      at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:70)
      at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
      at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
    Caused by: reactivemongo.api.commands.LastError: DatabaseException['<none>']
    

    使用ReactiveMongo 0.11.14,Play 2.5.4,Scala 2.11.7,MongoDB 3.4.0。

    谢谢!

    更新 - 神秘感增厚!

    根据@ Yaroslav_Derman的回答,我添加了一个.recover子句,如下所示:

    collectionRef.flatMap( c =>
      c.update( BSONDocument("_id" -> publicationWithId.id.get), publicationWithId.asInstanceOf[PublicationItem], upsert=true))
      .map(wr => {
        Logger.warn("Write Result: " + wr )
        Logger.warn("wr.inError: " + wr.inError)
        Logger.warn("*************")
        publicationWithId
      }).recover({
      case de:DatabaseException => {
        Logger.warn("DatabaseException: " + de.getMessage())
        Logger.warn("Cause: " + de.getCause())
        Logger.warn("Code: " + de.code)
        publicationWithId
      }
    })
    

    调用recover子句。这是日志:

    [info] application - Saving pub t3
    [warn] application - *************
    [warn] application - Saving publication     Publication(Some(BSONObjectID("5848101d7263468d01ff390d")),t3,2016-12-07,desc,auth,filename,None)
    [info] application - Resolving database...
    [info] application - Resolving database...
    [warn] application - DatabaseException: DatabaseException['<none>']
    [warn] application - Cause: null
    [warn] application - Code: None
    

    所以没有原因,没有代码,消息是“'<none>'”,但仍然是错误。是什么给了什么?

    我试图移动到0.12,但这导致了整个应用程序的一些编译错误,而且我不确定这会解决问题。所以我想首先理解什么是错的。

    更新#2: 迁移到reactive-mongo 0.12.0。问题依然存在。

3 个答案:

答案 0 :(得分:6)

通过降级到MongoDB 3.2.8解决了问题。事实上,reactiveMongo 0.12.0 not compatible with mongoDB 3.4

感谢所有关注此事的人。

答案 1 :(得分:2)

对于play reactivemongo 0.12.0你可以这样做

def appsDb = reactiveMongoApi.database.map(_.collection[JSONCollection](DesktopApp.COLLECTION_NAME))

def save(id: String, user: User, body: JsValue) = {
    val version = (body \ "version").as[String]
    val app = DesktopApp(id, version, user)

    appsDb.flatMap(
      _.insert(app)
        .map(_ => app)
        .recover(processError)
    )
  }

def processError[T]: PartialFunction[Throwable, T] = {
    case ex: DatabaseException if ex.code.contains(10054 | 10056 | 10058 | 10107 | 13435 | 13436) =>
      //Custom exception which processed in Error Handler
      throw new AppException(ResponseCode.ALREADY_EXISTS, "Entity already exists")

    case ex: DatabaseException if ex.code.contains(10057 | 15845 | 16550) =>
      //Custom exception which processed in Error Handler
      throw new AppException(ResponseCode.ENTITY_NOT_FOUND, "Entity not found")

    case ex: Exception =>
      //Custom exception which processed in Error Handler
      throw new InternalServerErrorException(ex.getMessage)
  }

您还可以在processError方法

中添加日志

答案 2 :(得分:1)

LastError WriteResult LastError inError

LastError实际上并不意味着错误,它可能意味着'<none>'对象的deprecated in 0.11, replaced select()属性成功检测它是否真实错误。正如我所看到的,read错误消息很可能不会出现错误。

以下是示例&#34;它是如何在0.10&#34;:you need to check