scala - Dealing with a Failed `Future` -
given following 2 methods:
def f: future[int] = future { 10 } def g: future[int] = future { 5 }
i'd compose them:
scala> import scala.concurrent.future import scala.concurrent.future scala> import scala.concurrent.future._ import scala.concurrent.future._ scala> import scala.concurrent.executioncontext.implicits.global import scala.concurrent.executioncontext.implicits.global scala> { | <- f | b <- g | } yield (a+b) res2: scala.concurrent.future[int] = scala.concurrent.impl.promise$defaultpromise@34f5090e
now, i'll call await.result
block until it's finished.
scala> import scala.concurrent.duration._ import scala.concurrent.duration._
as expected, 15
, since await.result
took future[int]
, returned int
.
scala> await.result(res2, 5.seconds) res6: int = 15
defining recoverfn
failed future:
scala> val recoverfn: partialfunction[throwable, future[int]] = { case _ => future{0} } recoverfn: partialfunction[throwable,scala.concurrent.future[int]] = <function1>
i try define failedfuture:
scala> def failedfuture: future[int] = future { 666 }.failed.recoverwith{ recoverfn } <console>:20: error: type mismatch; found : scala.concurrent.future[any] required: scala.concurrent.future[int] def failedfuture: future[int] = future { 666 }.failed.recoverwith{ recoverfn } ^
but, above compile-time error.
specifically, how can fix error? generally, future#recoverwith
typically how failed future
's handled?
the problem future#failed
always returns future[throwable]
. it's purpose is not fail future
, instead return failed projection of future
. means if original future
failed, converted successful future
holds exception. , if original future
succeeded, becomes failed, , holds nosuchelementexception
. error getting because you're recovering future[throwable]
future[int]
, has least upper-bound of future[any]
.
if you're trying play failed future
s, try instead:
scala> future.failed[int](new exception("???")).recoverwith(recoverfn) res4: scala.concurrent.future[int] = scala.concurrent.impl.promise$defaultpromise@6933711b scala> res4.value.get res5: scala.util.try[int] = success(0)
there nothing wrong recoverwith
.
Comments
Post a Comment