Reputation: 1803
I have a Try
that throws Exception. I want that Try
to become a Future
so I will be able to recoverWith
.
How can I convert the Try
into a Future
without handling any exceptions in the Try
(just in the Future with recover)?
note that Await is needed to test the result of your future
The code sample demonstrates what I had in mind but it also throws once reached (new RuntimeException("-------failed-------")
is what I get)
val t = Try(throw new RuntimeException("my"))
val resF : Future[String] = if (t.isSuccess)
Future.successful(t.get)
else
Future.failed(new RuntimeException("-------failed-------"))
val resFWithRecover = resF.recoverWith{
case NonFatal(e) =>
Future.successful("recoveredWith")
}
Await.result(resFWithRecover, Duration("5s"))
Upvotes: 11
Views: 16282
Reputation: 59
Future.fromTry
will run the Try code synchronously. From the documentation:
Creates an already completed Future with the specified result or exception.
Since your interface relies on Future, you may want to to run the Try itself asynchronously. This will be more efficient for most use cases. You can do it like this:
val f = Future {
val t = Try(...)
t match {
case Success(value) => value
case Failure(exception) => throw exception
}
}
f.recoverWith{...}
Upvotes: 0
Reputation: 13985
// you need to provide your try with type information in lhs
// as the rhs is not providing any type info
val t: Try[String] = Try(throw new RuntimeException("my"))
// Now you can easily get a Future[String] from this Try[String]
val f = Future.fromTry(t)
// or you can use pattern matching
val f2 = t match {
case Success(str) => Future.succesful(str)
case Failure(ex) => Future.failed(ex)
}
Upvotes: 1
Reputation: 953
There's no need to introduce Future if all you want to do is to use recoverWith (kind of like flatMap) on your Try object.
You could so something like the following:
val t = Try[String](throw new RuntimeException("my"))
val u = t.recoverWith{
case e => Success(s"ignoring exception ${e.getLocalizedMessage}")
}
u.foreach(println(_))
This results in the following output to the console:
ignoring exception my
Upvotes: 1
Reputation: 55569
... how do convert
Try
toFuture
without handling any exception in theTry
?
Use Future.fromTry
.
scala> val t = Try(throw new RuntimeException("my"))
t: scala.util.Try[Nothing] = Failure(java.lang.RuntimeException: my)
scala> val resF = Future.fromTry(t)
resF: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$KeptPromise@57cf54e1
scala> resF.recoverWith{
| case NonFatal(e) =>
| Future.successful("recoveredWith")
| }
res5: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@1b75c2e3
Upvotes: 25
Reputation: 14825
You can recoverWith
on Try
also
Use map
and recover
methods on Try
to produce Future.successful
and Future.failed
respectively and then get
on Try
val future =
Try {
throw new Exception("explosion")
}.map { result =>
Future.successful(result)
}.recover { case th =>
Future.failed(th)
}.get
Using Pattern Matching
val future =
Try {
throw new Exception("something")
} match {
case Success(value) => Future.successful(value)
case Failure(th) => Future.failed(th)
}
Upvotes: 0