Krishnnakumar R
Krishnnakumar R

Reputation: 372

Throwing exception when Actor returns Future[Option[None]] Akka Http

I have a case class

case class Fare(flightNumber: String, flightDate: LocalDate, amount: Int)

and an Actor

class FareDb extends Actor with ActorLogging {

  import FareDb._

  var fares: List[Fare] = List()

  override def receive: Receive = {
    case AddFare(fare) =>
      log.info(s"Adding fare $fare")
      fares = fares :+ fare

    case GetFare(flightNumber, flightDate) =>
      log.info(s"Getting Fare for FlightNumber $flightNumber and FlightDate $flightDate")
      sender() ! fares.find { fare => (flightNumber == fare.flightNumber & flightDate == fare.flightDate) }
  }

}

I also have a Route

object FareController extends App with FareJsonProtocol with SprayJsonSupport{
    val fareRoutes =
        (path("api" / "fare") & get & extractLog) { log =>
          parameter(Symbol("flightNumber").as[String],
            Symbol("flightDate").as(stringToLocalDate)) { (flightNumber: String, flightDate: LocalDate) =>
            log.info(s"Searching for Fare with FlightNumber $flightNumber & FlightDate: $flightDate")
            val fareFuture: Future[Option[Fare]] = (fareDb ? GetFare(flightNumber, flightDate)).mapTo[Option[Fare]]
            complete(fareFuture)
          }
        }
}

When I search for a Fare and "ask" the Actor with a flightNumber and flightDate, it returns a Future[Option[Fare]]. If it returns a fare, then allz good. I can just use complete(fareFuture) as I have SprayJson. But how to cater to a Future[None]?. I want to throw an exception for an empty result and send an HttpResponse accordingly. How do we do that? Thanks.

Upvotes: 1

Views: 73

Answers (1)

Ivan Stanislavciuc
Ivan Stanislavciuc

Reputation: 7275

I assume you'd like to return 404 when your future returns a None. You don't need to throw an exception to handle such cases.

You can modify the route in the following way to handle None.

Instead of complete(fareFuture) do the following

onSuccess(fareFuture) {
  case Some(fare) => complete(StatusCodes.OK -> fare)
  case None => complete(StatusCodes.NotFound)
}

Upvotes: 2

Related Questions