Reputation: 3089
Given this code
val f1: Future[Int] = Future { 5 } //Future.failed(new Exception("sorry"))
val f2: Future[Int] = Future { 6 }
val result : Future[Int] = f1.fallbackTo {
println("Fall back to that F")
f2
}
result contains the result of f1. However the code in the fallbackTo block is executed regardless of whether f1 fails or not. I was expecting the fallbackTo block to be only executed if f1 fails.
Perhaps my example is too simple (or just wrong), but what is the use of fallbackTo?
Upvotes: 13
Views: 3900
Reputation: 1320
Another way is to force f1 failure explicitly:
val f1 = Future.failed(new Throwable)
val f2: Future[Int] = Future { 6 }
val result : Future[Int] = f1.fallbackTo {
println("Fall back to that F")
f2
}
Upvotes: 0
Reputation: 15783
You are correct, f1
is returned if it's successful, if not f2
, the print you are seeing is because of the fact that the block is not evaluated lazily:
def fallbackTo[U >: T](that: Future[U]): Future[U]
So it seems that f2
is started when it's passed to fallbackTo
(and hence the print statement is executed). Probably it's a design choice, if it would have been lazily evaluated f2
would have been started only after the failure from f1
.
If you want to avoid this kind of behaviour you can use recoverWith
which is fired only after a failure:
f1.recoverWith{ case _ => println(123); Future { 6 } }
Upvotes: 27