Karel Horak
Karel Horak

Reputation: 1072

Handling errors in ReactiveMongo

I am working on a simple RESTful web service using Play Framework 2.1.5 and ReactiveMongo 0.9 using ReactiveMongo Play plugin. It has been a long time since I used Play Framework for the last time. I am trying to insert a document using:

def create = Action(parse.json) { request =>
  Async {
    val coll = db.collection[JSONCollection](...)
    val obj = Json.obj(
                "username" -> ...,
                ...
              )

    users.insert(obj).map { err => err match {
      case e if !e.ok => InternalServerError(Json.obj("result" -> 0, "error" -> e.message))
      case _ => Ok(Json.obj("result" -> 1))
    }}
  }
}

I have expected that once the query execution fails (e.g. due to the duplicate value in an index), I will handle it without any problem. But it is working differently - in case of failure a DatabaseException is thrown instead of satisfying the Promise[LastError] with an appropriate value. What am I missing please?

Upvotes: 0

Views: 1411

Answers (3)

Orar
Orar

Reputation: 958

I hope this simplifies your need...

def create = Action (parse.json) { request => 
   Async {
     val coll = db.collection[JSONCollection](...)
     val obj = Json.obj ("username" -> ...)
     users.insert(obj).map {
        case ins if ins.ok => OK (...)
        case ins => InternalServerError (...)
     } recover {
        case dex: DatabaseException => 
          log.error(..)
          InternalServerEror(...)
        case e: Throwable =>
          log.error (..)
          InternalServerError (...)
     }
   }
 }      

Upvotes: 0

panky
panky

Reputation: 137

Try this code-

def insert(coll: BSONCollection, doc: BSONDocument): Future[Unit] = {

val p = Promise[Unit]
val f = coll.insert(doc)
f onComplete {
  case Failure(e) => p failure (e)
  case Success(lastError) => {
    p success ({})
  }
}
p.future
}

Upvotes: 0

johanandren
johanandren

Reputation: 11479

When an exception happens in a future any calls to map will be ignored and the exception will be passed along the chain of futures.

Explicitly handling the exceptions in a chain of Futures can be done with recover and recoverWith. You can read more about it in the overview of futures in the scala-lang docs: http://docs.scala-lang.org/overviews/core/futures.html#exceptions

Upvotes: 2

Related Questions