Scala для понимания и опций

Я использую Scala / Slick 3.1 (это все через активатор типа "спрей-гладко-чванство"), и у меня выполняется 4 разных запроса, которые я хочу вернуть как один объект. Я пытаюсь объединить все фьючерсы в одно будущее.

Это работает, но проблема в том, что если запрос не выполняется (т. Е. Мы ищем то, чего не существует), возникает исключение времени выполнения.

Я думаю, что на самом деле я должен полностью отказаться от всего этого, если один запрос завершится неудачно, и в конечном итоге вернуть Future [Option]

Все это связано через спрей

поэтому код запроса выглядит так:

// .. snip .. FindById() 
      val a = db.run(q1.result) // Future[Seq[Tuple]]]
      val b = db.run(q2.result)
      val c = db.run(q3.result)
      val d = db.run(q4.result)

      // compose the futures together into one future
      val res = for {
    resA <- a
    resB <- b
    resC <- c
    resD <- d
  } yield {
       PhoneMerged(resA.head._1, resA.head._2, resB.map( x  => FeaturesSimple(x.featurename)).toList, resD.map(x => FeaturesvaluepairSimple(x.featuretype, x.featurevalue)).toList,
          resC.map(x => IncludedaccessorySimple(x.accessoryvalue)).toList, createPhoneImage(resA.head._1.devicemcd))
    }

Он вызывается с помощью

 onComplete((modules.phonesDAA ? FindById(id)).mapTo[Future[PhoneMerged]]) {
          case Success(phoneOption) =>  {
            println(phoneOption)
            complete(phoneOption)
            }
          case Failure(ex) => {
            println("uh oh")
            complete("{}")
          }
        }

в конечном итоге я хочу вернуть либо сериализованный объект PhoneMerged JSON (который работает, если я ищу действительный идентификатор), либо пустой json "{}" ...

У кого-нибудь есть мысли о том, как правильно обработать результат / обработать ошибку?


person bonez    schedule 28.10.2015    source источник


Ответы (1)


Вы можете заставить функцию FindById возвращать Future[Option[PhoneMerged]] и обрабатывать случай сбоя внутри с помощью комбинатора Future, такого как recover.
Например:

  val a = db.run(q1.result)
  // Future[Seq[Tuple]]]
  val b = db.run(q2.result)
  val c = db.run(q3.result)
  val d = db.run(q4.result)

  // compose the futures together into one future
  val res = for {
    resA <- a
    resB <- b
    resC <- c
    resD <- d
  } yield {
      Some(PhoneMerged(resA.head._1, resA.head._2, resB.map(x => FeaturesSimple(x.featurename)).toList, resD.map(x => FeaturesvaluepairSimple(x.featuretype, x.featurevalue)).toList,
        resC.map(x => IncludedaccessorySimple(x.accessoryvalue)).toList, createPhoneImage(resA.head._1.devicemcd)))
    } recover {case e: YourExceptionType => None}
person Vered Rosen    schedule 28.10.2015