Reputation: 9705
I started migrating my Scala 2.11 code base to Scala 2.12. In my application I had a method that looked like this:
Future {
someMethodReturningTry()
} onSuccess {
case Success(result) => processResult()
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
Now, if you compile this with Scala 2.12, you'll get:
method onSuccess in trait Future is deprecated (since 2.12.0): use
foreach
oronComplete
instead (keep in mind that they take total rather than partial functions)
So I started exploring how I could solve this in an elegant way.
The someMethodReturningTry()
method really should return a Try[]
, since it involves parsing some text structure and that might fail, so I prefer to keep the return type for that method the same.
The best I could think of is
Future {
someMethodReturningTry()
} flatMap {
case Success(result) => Future.successful(result)
case Failure(reason) => Future.failed(reason)
} onComplete {
case Success(result) => processResult()
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
But that feels a bit redundant: creating a Future
just to model the fact that something in the future (which already is captured inside a Future
) went well.
This approach creates an extra Future
which I hope to get rid of, but I can't figure out how. Any suggestions?
Upvotes: 1
Views: 954
Reputation: 51271
It's not clear to me why you don't just...
Future {
someMethodReturningTry() match {
case Success(result) => processResult(result)
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
}
You're free to handle, or ignore, the Future
failure separately.
Upvotes: 3
Reputation: 19527
You could adjust your pattern matching in the following way:
Future {
someMethodReturningTry()
} onComplete {
case Success(Success(result)) => processResult()
case Success(Failure(reason)) => log.error(s"Couldn't do it: ${reason.getMessage}")
case Failure(reason) =>
log.error(s"The future failed: ${reason.getMessage}")
// or do nothing
}
Note that the onSuccess
callback is executed only if the Future
succeeds, so your original code didn't do anything if the Future
contained an exception. If that is your intent, you can leave the case Failure(reason) =>
clause above blank (but it's probably more helpful to retain the error logging as shown).
Upvotes: 2