JohnBigs
JohnBigs

Reputation: 2811

recover future is not responding as expected (scala)

I have a custom case class exception:

 case class RecordNotFoundException(msg: String) extends RuntimeException(msg)

In my dao I have a method to pull object from the database, which returns future, and if this future fail I throw my RecordNotFoundException exception:

  def getPerson(personId: String): Future[Person] = {
    val q = quote {
      query[Person].filter(per => per.personId == lift(personId))
    }
    ctx.run.map(_.head) recover {
      case ex: NoSuchElementException => throw RecordNotFoundException(s"personId $personId does not exist")
    }
  }

in another method I call getPerson method, so I added recover to this other method and I want to return something when the future fails with RecordNotFoundException:

def run(personDao: PersonDao): Future[String] = {
  if (true) {
    for {
      person <- personDao.getPerson("some_user_id")
      something <- someOtherFuture
    } yield {
      // what happens here not relevant
    }
  } else {
    Future.successful("got to the else")
  } recover {
    case e: RecordNotFoundException => "got to the recover"
  }
}

so basically I expect the run() method to return "got to the recover" when getPerson fails, but from some reason I dont get to the recover...the failure goes back to the controller.

does anyone knows why is that please?

Upvotes: 0

Views: 99

Answers (1)

o-0
o-0

Reputation: 1799

First of all look at where your recover is. Why don't you move it to the last line of the method? Something like:

def getPerson(id: String): Future[String] = Future("Andy")
def someOtherFuture(id: String) = Future("Mandy")

case class RecordNotFoundException(msg: String) extends RuntimeException(msg)

def run(personDao: String): Future[String] = {
  if (true) 
    for {
      person <- getPerson("some_user_id")
      something <- someOtherFuture("1")
    } yield {
      person
    }
  else Future.successful("got to the else")
}recover { case e: RecordNotFoundException => "got to the recover"}

Also move the recover for the getPerson as well.

In my opinion there is nothing wrong about using Future/recover in your models and/or services and then the exception is going back to the controller. Then the controller method deals with the customized exception; and return InternalServerError or BadRequest to a user or the API call.

Upvotes: 1

Related Questions