I am a scala beginner and need some help to convert the below java “retrywhen” to scala.
Observable.merge(observables).retryWhen(errors -> errors.flatMap(error -> {
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything other than IOException, don’t retry
return Observable.error(error);
})
)
I tried as below but gives me “missing parameter type” for “flatmap”.
Observable.merge(observables).retryWhen((errors: Observable[_ <: Throwable]) => errors.flatMap(error => if (isInstanceOf[IOException]) Observable.just(null) else Observable.error(error) ))
Thank you.
First, a few suggestions for creating posts like this:
- Put code blocks inside “```” (triple backticks) to improve readability.
- Reference libraries you are using (where does
Observable
come from?) and provide type information for identifiers originating outside the quoted code (what is observables
?).
- Quote error messages verbatim.
Assuming you’re using RxJava 2 and observables
is a Java Iterable<Observable<T>>
for whatever concrete T
, I cannot reproduce any compiler error with your version.
A slightly more idiomatic Scala version:
Observable.merge(observables).retryWhen(_.flatMap {
case _: IOException => Observable.just(null)
case error => Observable.error(error)
}
)
(No guarantees for correctness - I don’t know RxJava and haven’t tested this.)
However, I’d strongly suggest to trace back a few steps for a variety of reasons.
- It’s easier to familiarize yourself with Scala via a text book and small pieces of standalone code before attempting to convert legacy Java code.
- There’s better, Scala-native choices for reactive streams libraries than RxJava: akka-streams, Monix,…
- You’ll want to get rid of Java residue (like
null
usage and Java collections just in this snippet), so a port from Java will always turn out to be a complete overhaul or even rewrite rather than a faithful translation.
2 Likes
Thank you. I see the below error when compiling your and my version.
missing parameter type for expanded function ((x$1) => x$1.flatMap( match {
case (_: IOException) => Observable.just(null)
case (error @ _) => Observable.error(error)
Then you’ll have to provide an SSCCE so others can reproduce your problem. This should include at least a standalone source code file and the library dependencies (from your build.sbt
or whatever build tool you’re using).
I’d still strongly suggest to take a different approach to Scala than trying to convert Java code based on a rather advanced library whose Scala binding has recently been abandoned in favor of other alternatives.
1 Like
Apologies - I just reopened the project where I tried this, and I’m seeing the same error.
No idea why I hadn’t seen it the last time, maybe I trusted the presentation compiler and didn’t force a full build.
I can’t formally explain the cause of the problem, but I guess the compiler gets lost in the mix of overloads, Java wildcards and custom functional interfaces. Explicitly providing the right Function
type for the #flatMap()
application seems to do the trick.
val retryError: io.reactivex.functions.Function[Throwable, ObservableSource[String]] = {
case _: IOException => Observable.just(null)
case error => Observable.error(error)
}
Observable.merge(observables.asJava).retryWhen(_.flatMap(retryError))
…but I guess this serves to illustrate why I don’t think it’s a good idea to move on with a faithful translation of this Java code…