I have a function saveToDB()
that calls another function db.writeDocument()
in another class called DB.scala
. The saveToDB()
function receives a JSON message and sends it to the writeDocument()
and expects a future
to be returned.
So, in the code below, you can see that db.writeDocument(message)
returns a function which is being .map
'ed to see either a success result or a failure.
Everything works great on the success side of things, but when I kill the MongoDB server, reactivemongo.core.actors.Exceptions$PrimaryUnavailableException$: MongoError['No primary node is available!']
is never caught and all I get is the 500 Internal Server Error
with response body containing Execution exception
def saveToDB(message: JsValue): Future[JsValue] = {
db.writeDocument(message).map { result =>
val resultJson = Json.obj("transactionID" -> (message \ "transactionID").get, "campaignID" -> (message \ "campaignID").get,
"status" -> "OK", "message" -> ("Valid Request Received"))
resultJson
}.recover { case e: Exception => {
BadRequest("Please check your MongoDB server" + e.toString)
Json.toJson("status -> error")
}
}
def writeDocument(json: JsValue): Future[WriteResult] = {
val db = getDBConnection
val collection = db.collection[JSONCollection]("Messages")
val document = json.as[JsObject]
val future = collection.insert(document)
future.onComplete {
case Failure(e) => {
throw e
}
case Success(result) =>
}
future
}
}
To be completely fair about my question, I am trying to use the saveToDB()
in the following way: (I have tried my best to explain this and please let me know if you need more explanation.)
val saveResponseFromDB = saveToDB(message)
Future.firstCompletedOf(Seq(saveResponseFromDB, timeoutFuture)).map {
case resultJson: JsObject => {
val status = ((resultJson \ "status").get)
Ok(resultJson)
} case _ => BadRequest(Json.obj("campaignID" -> campaignID,
"status" -> "error", "message" -> "Error reading from the Database. Is it Down?") )
}
EDIT 1:
def getDBConnection: DefaultDB = {
val driver = new MongoDriver
val connection = driver.connection(List(hostName))
val db = connection(dbName)
db
}