LoginSignup
4
3

More than 5 years have passed since last update.

ScalaのFutureで例外を飛ばす時の罠メモ

Last updated at Posted at 2018-11-09

忘れやすいので記述。

マル

Future.failed(new Exception)

Future(throw new Exception)

ダメ

Future.failed(throw new Exception)

Future(new Exception)

理由

※コメントを頂き訂正しました

Future では ExecutonContext が求められるという差異もある。

Future(throw new Exception) recoverできる。

scala> val a = Future(throw new Exception)
a: scala.concurrent.Future[Nothing] = Future(<not completed>)
scala> val c = a.recoverWith{ case _ => Future("ok") }
c: scala.concurrent.Future[String] = Future(<not completed>)
scala> c
res15: scala.concurrent.Future[String] = Future(Success(ok))

Future.failed(new Exception) recoverできる。

scala> val e = Future.failed(new Exception)
e: scala.concurrent.Future[Nothing] = Future(Failure(java.lang.Exception))
scala> val f = e.recoverWith{ case _ => Future("ok") }
f: scala.concurrent.Future[String] = Future(<not completed>)
scala> f
res19: scala.concurrent.Future[String] = Future(Success(ok))

https://qiita.com/mtoyoshi/items/f68beb17710c3819697f#failed に書かれているような Successful[Throwable] を作るわけではなさそう? Failure[Throwable] が作られている。

Future(new Exception) 引数に渡す地点でThrowが飛ぶ。 recoverできない。

scala> Future.failed(throw new Exception).recoverWith{ case _ => Future("ok") }
java.lang.Exception
  ... 28 elided

Future(new Exception) Successful[Exception] が返る。 recoverできない。

scala> val b = Future(new Exception)
b: scala.concurrent.Future[Exception] = Future(<not completed>)
scala> val d = b.recoverWith{ case _ => Future("ok") }
d: scala.concurrent.Future[java.io.Serializable] = Future(<not completed>)
scala> d
res16: scala.concurrent.Future[java.io.Serializable] = Future(Success(java.lang.Exception))
4
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3