Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return Single.error() when one of sources in Single.zip fails?

I have two sources of Singles, which I combine into one Single of Pair.

Let's say we have two methods for these sources:

private Single<String> single1() {} 
private Single<String> single2() {}

Now I combine them into Single<Pair<String, String>

private Single<Pair<String, String> combineSingles() {
    Single.zip(single1(), single2(), BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2))
}

When one of the methods (single1 or single2) returns Single.error(), I get UndeliverableException cause error isn't handled in zip operator. I want instead to return Single.error() from combineSingles() method, how can I achieve that?

like image 822
Nominalista Avatar asked Aug 17 '17 18:08

Nominalista


3 Answers

try this

private Single<Pair<String, String> combineSingles() {
    try {
        Single.zip(single1(), single2(), BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2))
    } catch (Exception e) {
        Single.error()
    }
}

by the way i was first to suggest the try catch method :)

like image 127
Max Alexander Hanna Avatar answered Oct 13 '22 01:10

Max Alexander Hanna


onErrorResumeNext(...) is your friend, which is the try/catch equivalent for RxJava.

Here is the complete example

public final class RxTest {

    private static Single<String> single1() {
        return Single.just("1");
    }
    private static Single<String> single2() {
        return Single.error(new RuntimeException("single2"));
    }

    private static Single<Pair<String, String>> combineSingles() {
        return Single.zip(single1(), single2(), Pair::new)
                .onErrorResumeNext(Single.error(new RuntimeException("zip")));
    }

    public static void main(String[] args) {
        combineSingles()
                .test()
                .assertError(RuntimeException.class)
                .assertError(throwable -> "zip".equals(throwable.getMessage()));
    }
}
like image 24
Deepak Azad Avatar answered Oct 13 '22 03:10

Deepak Azad


How about the usual try/catch logic?

Single<String> single1;
try {
    single1 = single1();
} catch (RuntimeException e) {
    return Single.error();
}
Single<String> single2;
try {
    single2 = single2();
} catch (RuntimeException e) {
    return Single.error();
}
return Single.zip(single1, single2, BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2))

Or if you want to replace the faulty value with Single.error(), then

Single<String> single1;
try {
    single1 = single1();
} catch (RuntimeException e) {
    single1 = Single.error();
}

And so on.

like image 33
Roman Puchkovskiy Avatar answered Oct 13 '22 01:10

Roman Puchkovskiy