2

I'm RxJava newbie, and I've got following problem. Say I have sequence of items and on of items propagates error, I want to ignore it and to continue processing other items.

I have following snippet:

    Observable.from(Arrays.asList("1", "2", "3"))
            .map(x -> {
                if (x.equals("2")) {
                    throw new NullPointerException();
                }
                return x + "-";
            })
            .onExceptionResumeNext(Observable.empty())
            .subscribe(System.out::println);

I'm getting: 1-

But I want to get: 1- , 3-

How can I do that?

corvax
  • 1,095
  • 1
  • 10
  • 35
  • Possible duplicate of [How to ignore error and continue infinite stream?](http://stackoverflow.com/questions/28969995/how-to-ignore-error-and-continue-infinite-stream) – Ivan Nov 03 '16 at 17:27

1 Answers1

2

the trick is to wrap the value, which would be transformed somehow, into a new observable and flatmap over it as in the following example. Each value in the flatMap can now throw a exception and handle it value by value. Becuase the substream in flatMap consists only of one element, it does not matter if the observable will be closed after onError. I use RxJava2 as test-environment.

@Test
public void name() throws Exception {
    Observable<String> stringObservable = Observable.fromArray("1", "2", "3")
            .flatMap(x -> {
                return Observable.defer(() -> {
                    try {
                        if (x.equals("2")) {
                            throw new NullPointerException();
                        }
                        return Observable.just(x + "-");
                    } catch (Exception ex) {
                        return Observable.error(ex);
                    }
                }).map(s -> {
                    if (s.equals("3-")) {
                        throw new IllegalArgumentException();
                    }
                    return s + s;
                }).take(1)
                        .zipWith(Observable.just("X"), (s, s2) -> s + s2)
                        .onErrorResumeNext(Observable.empty());
            });

    TestObserver<String> test = stringObservable.test();

    test.assertResult("1-1-X");
}
Sergej Isbrecht
  • 3,842
  • 18
  • 27
  • 1
    Thank you very much! I have another question: so if I have ten transformers and each of them can throw exception so I should wrap each of them with this code??? – corvax Nov 02 '16 at 14:41
  • As always the answer is: it depends what you want to do. If you want to do not only the map operator onto the new observable, but some others, I would recommend to place them before onErrorResumeNext. If one of the operators will fail, the value, for example 2, will fail and instead an empty observable will be returned. If you want to handle backup values on every operator, you would re-wrap the substream into a new stream and flatmap over it. Please provide some more code. – Sergej Isbrecht Nov 02 '16 at 14:50