The first function testThrowException
does not return a Future in the case that it gets a 0
as input. Therefore, the program keeps running until the exception appears.
However, as seen in the source code pasted below, the Future.map
always returns another future:
def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
val p = Promise[S]()
onComplete { v => p complete (v map f) }
p.future
}
Just defining a Future does not print out its results and it also does not print exceptions thrown. You would need to define the onSuccess
, onFailure
, or onComplete
to do so. However, if a print statement exists in the body of the Future, then it will execute:
def addOne(number: Int): Int = {
if (number == 0) {
// you can also print the exception instead of just throwing it.
throw new Exception("number is 0")
} else {
println("success")
1 + number
}
}
Future { addOne(1) } // scala.concurrent.Future[Int] = Future(Success(2))
// the above also prints "success"
Future { addOne(0) } // scala.concurrent.Future[Int] = Future(Failure(java.lang.Exception: number is 0))
// the above does not print anything unless the exception is printed before thrown in `addOne`
You can also use onComplete
, to handle both success and/or failure:
// prints "got error" plus the stack trace
- List item
Future {0}.map(addOne).onComplete {
case Success(value) => println(s"got $value")
case Failure(t) => println("got error: " + t.getStackTrace.mkString("\n"))
}
Note that the imports used were:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}