Прервать цепочку карт будущего и вернуть левую - PullRequest
3 голосов
/ 08 января 2020

Как я могу вернуть Левый в середине будущей цепочки карт и затем потерпеть неудачу в будущем? Я отправляю пример для уточнения.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object TestApp extends App {

  final case class Message(statusCode: Int, data: String)
  final case class Success(data: String)
  final case class Failure()

  val msg = Message(500, "My data")
  val future = Future { msg }

  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] = {
    future.map { msg =>
      // Evaluate msg here - if failure, make this feature fail and then return Left(Failure), otherwise, continue in the chain
      msg
    }.map(_.data).map(data => Right(Success(data)))
  }
}

1 Ответ

2 голосов
/ 08 января 2020

Один из вариантов - выбросить исключение, которое завершится с ошибкой Future, а затем recover в Left, например

  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] =
    future
      .map(msg => if (msg.statusCode == 500) throw new RuntimeException("boom") else msg)
      .map(_.data)
      .map(data => Right(Success(data)))
      .recover{case ex => Left(Failure())}

Другой вариант - transform, например

.
  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] = {
    future
      .map(msg => if (msg.statusCode == 500) throw new RuntimeException("boom") else msg)
      .map(_.data)
      .transform(v => scala.util.Success {
        v.toEither
          .map(v => Success(v))
          .left.map(e => Failure())
      })
  }

Внимание, вы определили свои Success/Failure тени Scala 1012 *.

...