Search code examples
mongodbscalareactivemongo

Pattern matching after update with ReactiveMongo


I try to make pattern matching for checking error after an update document on mongodb with scala.

def update(id: BSONObjectID, post: Post): Future[WriteResult] =
collection.flatMap(_.update.one(BSONDocument("_id" -> id), BSONDocument(
  f"$$set" -> BSONDocument(
    "title" -> post.title,
    "description" -> post.description
  )
),
true))

this is my update function in productrepository, and this is my controller

def update (id: String) = Action.async(parse.json) { /*implicit request =>*/
val bsonId = BSONObjectID.parse(id)
_.body.validate[Post].map { post => 
    postsRepo.update(bsonId.get, post).map { 
      case Some(post) => Ok(Json.toJson(post))
      case _ => NotFound
      //  _ => Created          
    }
  }.getOrElse(Future.successful(BadRequest("Invalid Format")))

}

I obtain this error:

constructor cannot be istantiated to expected type;
Found Some[A]
Required Reactivemongo.api.command.writeResult

My goal is to run pattern matching after update


Solution

  • If you have a look at IDE/compiler message, you can see that result of update operation is Future[UpdateWriteResult], so matching on Option in Future.map cannot be OK.

    If you read the documentation, you will find a "error handling" section, explaining how to recover write result according DB code or message.

    val done: Future[Unit] = future.map(_ => {}).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")
    
        case _ => ()
      }
    

    If you are trying to produce a specific response if nothing has been updated, it's not to be done with pattern matching, but just check UpdateWriteResult.n (number of updated docs) in .map.