Observer.onError срабатывает непоследовательно

Я использую Retrofit для доступа к моему API следующим образом:

public interface UserService {
    ...
    @POST("/user/login")
    public Observable<User> register(@Body() User user);
}

Вот как я получаю доступ к своему API:

mUserService.register(user)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
    @Override
    public void onCompleted() {
    ....
    }

    @Override
    public void onError(Throwable e) {
    ....
    }

    @Override
    public void onNext(User user) {
    ....
    }
});

Это работает отлично, за исключением случаев, когда возникает исключение (например, IOException или время ожидания соединения), метод onError не запускается, вместо этого я получаю исключение в основном потоке, которое завершает мое приложение.

Однако в некоторых случаях (например, когда вызов API отвечает кодом состояния 400) метод onError запускается, как и ожидалось.

После копания вывода logcat я заметил эту строку (не знаю, как я должен с этим бороться)

rx.exceptions.OnErrorFailedException: произошла ошибка при попытке передать ошибку в Observer.onError

Может ли кто-нибудь сообщить мне, где я делаю что-то неправильно?


person bentesha    schedule 21.07.2014    source источник


Ответы (2)


В моем предыдущем опыте работы с RxJava OnErrorFailedException означает, что при обработке другого исключения в методе onError возникло исключение.

Если вы не видите трассировку стека реальной причины, возможно, это связано с ошибкой в ​​RxJava с CompositeException (версии 0.19.2 и выше) https://github.com/Netflix/RxJava/issues/1405

В качестве обходного пути попробуйте поместить код onError в блок try-catch и записать исключение. Таким образом, вы увидите, в чем проблема с вашей onError реализацией, и сможете решить эту проблему.

@Override
public void onError(Throwable e) {
   try {
      ...
   catch(Throwable e) {
      // Log the exception
   }
}
person tomrozb    schedule 21.07.2014
comment
Проблема в том, что метод onError вообще не вызывается. Так что не нужно будет оборачивать его блоком try-catch. - person bentesha; 22.07.2014
comment
У вас есть фрагмент кода, показывающий ситуацию, в которой метод onError не вызывается, несмотря на то, что выдается исключение? - person tomrozb; 22.07.2014
comment
У меня такая же проблема. Метод onError от подписчика никогда не вызывается, но если я использую обратный вызов, он вызывается отлично. Есть новости об этом? - person Juan Saravia; 15.05.2015
comment
В последней версии у меня была эта ошибка из-за NPE в onError (), поэтому ваш try catch позволил мне определить проблему и добавить исправление. Спасибо - person mrroboaat; 27.09.2015
comment
Мой Looper.prepare() не вызывался. Отличное предложение! - person JehandadK; 29.09.2016

вы можете использовать unsafe unsafeSubscribe.

...
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.unsafeSubscribe(new Observer<User>() {
    @Override
    public void onCompleted() {
    ....
    }

    @Override
    public void onError(Throwable e) {
    ....
    }

    @Override
    public void onNext(User user) {
    ....
    }
});
...
person AbdulMomen عبدالمؤمن    schedule 31.08.2016