How can I return a Left in the middle of a future map chain and then fail the future? I am sending an example to clarify.
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)))
}
}
One option is to throw an exception which will fail the Future and then recover to a Left like so
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())}
Another option is to transform like so
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())
})
}
Warning, you have defined your own Success/Failure which shadows Scala's Success/Failure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With