10

I am using Retrofit to access my API as follows:

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

Here is how I access my 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) {
    ....
    }
});

This works perfectly well, except when there is an exception (i.e. IOException, or when connection times out), the onError method doesn't get fired, instead I get an exception on the main thread which terminates my application.

However, for some cases (such as when the API call responds with status code 400), the onError method is fired as expected.

After digging the logcat output, I have spotted this line, (not sure how I am supposed to deal with this)

rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError

Can someone let me know where I am doing things wrong?

bentesha
  • 898
  • 9
  • 14

2 Answers2

15

In my previous experience with RxJava the OnErrorFailedException means that an exception occurred while handling another exception in the onError method.

If you don't see stack trace of the real cause it's probably due the bug in RxJava with CompositeException (versions 0.19.2 and above) https://github.com/Netflix/RxJava/issues/1405

As a workaround try to wrap your onError code within try-catch block and log the exception. This way you will see what's the problem with your onError implementation and you will be able to solve the problem.

@Override
public void onError(Throwable e) {
   try {
      ...
   catch(Throwable e) {
      // Log the exception
   }
}
tomrozb
  • 25,773
  • 31
  • 101
  • 122
  • 1
    The issue is the onError method doesn't get called at all. So there will be no need to wrap it with a try-catch block. – bentesha Jul 22 '14 at 04:23
  • Do you have any code snippet that shows situation in which the onError method is not called despite of exception is being thrown? – tomrozb Jul 22 '14 at 11:12
  • I'm having the same issue. The onError method from the subscriber is never called but if I use a callback it's called perfectly. Any news about this? – Juan Saravia May 15 '15 at 01:11
  • 1
    WIth the latest version, i had this error due to NPE in onError () so your `try catch` allowed me to identify the problem and add a fix. Thx – mrroboaat Sep 27 '15 at 07:53
  • 1
    Mine was Looper.prepare() not called. Excellent suggestion! – Pinser Sep 29 '16 at 05:01
0

you can use 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) {
    ....
    }
});
...