简体   繁体   中英

Can a Future throw an exception caught by a caller?

When I run the code below it terminates and nothing happens, is there a way to catch the exception in future2.map ?

object TestFutures1 {
  val future1 = Future { 
    throw new Exception("error") 
    }
}

object TestFutures2 extends App {
  val future2 = TestFutures1.future1
  future2.map { result => println(result) }
  Thread.sleep(5000)
}

Generally speaking, there are two options (with some sub-options) to handle future exceptions.

  1. You can add a callback that will be called when the future completes with an exception:

     future2 .map { result => println(result) } .onFailure { exc => exc.printStackTrace } 

1a. .onFailure is only used for side effects, you cannot use, for example, to handle the exception. If you want to handle in and rescue the future, you can use .recover or .recoverWith (the only different between the two is that the latter takes a function that returns a Future , while the former deals with the actual result, same idea as map vs. flatMap :

    future2
      .map(println)
      .recover { case e => 
         e.printStackTrace
         "recovered"
      }.map(println)
  1. The other option is to wait for the future to complete, and access it's result:

     try { // Instead of Thread.sleep - you don't need that: Await.result(future2, 2 seconds) } catch { case exc => exc.printStackTrace } 

Except @Dima's answer, also can use onComplete to catch failure, like:

  val re = future2.map { result => println(result) }
  re onComplete {
    case Success(s) => ...
    case Failure(e) => e.printStackTrace()
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM