2016-08-02 2 views
2

фонRxJava Ошибка Почтовый оператор Работа с итератора

У меня есть процесс, который использует RxJava, чтобы получить данные из разных мест на основе списка. Каждый предмет получает другой метод (все возвращаемые Observables). Из-за того, что N элементов для получения логического оператора для использования - zip с итератором.

Проблема

Приведенный ниже код работает, как ожидалось, но это, кажется, «неправильно», что мне нужно try-catch блок, чтобы поймать исключение, брошенный getBigFoo() - которая возвращает FooNotFoundException. Не покрывают ли другие операторы, связанные с ошибкой, такие как onErrorResumeNext() и onErrorReturn()?

private Observable<Bar> processFoos(List<Foo> foos) { 

     List<Observable<? extends IBar>> observablesToZip = new ArrayList<>(); 

     for(Foo foo : foos) { 

      switch (foo.getType()) { 

       case BIG_FOO : 

        try { 
         observablesToZip.add(getBigFoo(foo.getId())); 
        } catch (Exception exception) { 
         //do nothing - but this seems wrong 
        } 
      } 
     } 

     return Observable.zip(observablesToZip, results -> mergeFoosIntoBar(results)); 
    } 

Попытки

Попытка ниже, кажется, не поймать исключение генерируется. Я не понимаю, почему, поскольку в последовательности нет технических элементов вверх или вниз, так что Observable.empty() должен работать?

private Observable<Bar> processFoos(List<Foo> foos) { 

     List<Observable<? extends IBar>> observablesToZip = new ArrayList<>(); 

     for(Foo foo : foos) { 

      switch (foo.getType()) { 

       case BIG_FOO : 
        observablesToZip.add(getBigFoo(foo.getId().onErrorResumeNext(Observable.empty())); 
      } 
     } 

     return Observable.zip(observablesToZip, results -> mergeFoosIntoBar(results)); 
    } 

ответ

0

@dwursteisen был на правильный ответ, но не совсем там.

Мой вопрос заключается в том, что я бросал новый FooNotFoundException:

throw new FooNotFoundException() 

Но что мне нужно было сделать:

return Observable.error(new FooNotFoundException()); 

Тогда в моей Zip функции:

observablesToZip.add(getBigFoo(foo.getId())).onExceptionResumeNext(Observable.just(null); 

Использование вышеприведенной комбинации означает, что общая последовательность не прерывает и возвращает ошибку, когда отдельный наблюдатель vables разрешены и потенциально бросают ошибки.

1

Возможно, вы захотите использовать defer. getBigFoo не должен генерировать исключение, а вместо этого возвращать Observable по ошибке. Так defer может помочь вам исправить:

Observable<IBar> obs = Observable.defer(() -> { 
      try { 
       return getBigFoo(foo.getId()); 
       } catch (Exception ex) { 
        return Observable.error(ex); 
       } 
}); 
observablestoZip.add(obs); 
+0

Благодарим за ответ, не проталкивает проблему в другом месте. Мне может потребоваться отсрочка, однако, если getBigFoo либо возвращает Observable.just (foo), либо Observable.error (new FooNotFoundException()), то разве операторы ошибок не поймут это? –

+0

, если getBigFoo не вызывает никаких исключений, но вместо этого возвращает Observable (Observable.just() или Observable.error()), то отложить это бесполезно. Я использую defer здесь только для того, чтобы имитировать то, что getBigFoo, на мой взгляд, должен делать (то есть: не бросать никаких исключений). – dwursteisen

+0

OK - поэтому makeend getBigFoo возвращает Observable.error() как я могу его поймать без блока try-catch? –

0

Не могли бы вы сделать getBigFoo (foo.getId()) бросить RuntimeException вместо Exception ?. Все исключения на конвейере должны быть захвачены, но не время выполнения.

Посмотрите на этот глупый пример

  /** 
* Here is a silly example how runtimeExceptions are not needed 
*/ 
@Test 
public void observableRuntimeException() { 
    Integer[] numbers = {0, 1, 2, 3, 4, 5}; 

    Observable.from(numbers) 
       .doOnNext(number -> throwRuntimeException()) 
       .doOnError(t -> System.out.println("Expecting illegal argument exception:" + t.getMessage())) 
       .subscribe(); 

} 

private void throwRuntimeException() { 
    throw new RuntimeException(); 
} 

вы можете увидеть больше примеров здесь https://github.com/politrons/reactive

+0

«FooNotFoundException extends IllegalArgumentException» может быть обновлен, чтобы расширить «RuntimeException» - это даст ему преимущество. –

+0

Просто попробовал это, без кубиков. Исключение не поймано doOnError, и процесс взрывается. Хорошая идея. –

Смежные вопросы