Подтвердить что ты не робот

Scala восстановить или восстановить

Мы разрабатываем некоторые системы в нашей компании в Scala, и у нас есть некоторые сомнения. Мы обсуждали, как отображать будущие исключения, и мы не знаем, когда мы должны использовать опцию 1 или вариант 2.

val created: Future[...] = ???

Вариант 1:   

val a = created recover {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    throw new business.ABusinessException("Failed ...", e) 
}

Вариант 2:

val a = created recoverWith {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    Future.failed(new business.ABusinessException("Failed ...", e))
}

Может кто-нибудь объяснить, когда я должен сделать вариант 1 или вариант 2? Что такое diff?

4b9b3361

Ответ 1

Хорошо, ответ четко описан в scaladocs:

  /** Creates a new future that will handle any matching throwable that this
   *  future might contain. If there is no match, or if this future contains
   *  a valid result then the new future will contain the same.
   *
   *  Example:
   *
   *  {{{
   *  Future (6 / 0) recover { case e: ArithmeticException => 0 } // result: 0
   *  Future (6 / 0) recover { case e: NotFoundException   => 0 } // result: exception
   *  Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3
   *  }}}
   */
  def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = {

  /** Creates a new future that will handle any matching throwable that this
   *  future might contain by assigning it a value of another future.
   *
   *  If there is no match, or if this future contains
   *  a valid result then the new future will contain the same result.
   *
   *  Example:
   *
   *  {{{
   *  val f = Future { Int.MaxValue }
   *  Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue
   *  }}}
   */
  def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = {

recover завершает простой результат в Future для вас (аналог map), а recoverWith ожидает Future в качестве результата (аналог flatMap).

Итак, вот эмпирическое правило:

Если вы восстановите что-то, что уже возвращает Future, используйте recoverWith, в противном случае используйте recover.

обн В вашем случае предпочтительнее использовать recover, так как recover перенесет ваше исключение в Future для вас. В противном случае нет выигрыша в производительности или что-то еще, поэтому вы просто избегаете какого-либо шаблона.