Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle onError inside RxJava. I am getting "OnErrorNotImplementedException"

In my app I am using ReactiveLocationProvider library (link). I subscribe for updates in the onCreate method. It works fine when the device is online but if I switch my wifi off and wait for the next background location updates the device OnErrorNotImplementedException. This is the log:

12-30 00:05:44.711 12237-12237/koemdzhiev.com.stormy E/AndroidRuntime: FATAL EXCEPTION: main
 Process: koemdzhiev.com.stormy, PID: 12237
 java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60)
     at android.os.Handler.handleCallback(Handler.java:739)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5292)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
  Caused by: rx.exceptions.OnErrorNotImplementedException: Timed out waiting for response from server
     at rx.Observable$27.onError(Observable.java:7535)
     at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:154)
     at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197)
     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170)
     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5292) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
  Caused by: java.io.IOException: Timed out waiting for response from server
     at android.location.Geocoder.getFromLocation(Geocoder.java:136)
     at pl.charmas.android.reactivelocation.observables.geocode.ReverseGeocodeObservable.call(ReverseGeocodeObservable.java:34)
     at pl.charmas.android.reactivelocation.observables.geocode.ReverseGeocodeObservable.call(ReverseGeocodeObservable.java:13)
     at rx.Observable.unsafeSubscribe(Observable.java:7710)
     at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
     at java.lang.Thread.run(Thread.java:818)

MainActivity code:

public class MainActivity extends AppCompatActivity {
    ReactiveLocationProvider locationProvider;
Observable<List<Address>> reverseGeocodeObservable;


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //-----------MY CODE STARTS HERE-----------------
    //check if the user previously has seen the whats new message...
    sharedPref = getPreferences(Context.MODE_PRIVATE);
    editor = sharedPref.edit();
    if (sharedPref.getInt(getString(R.string.saved_if_whats_new_seen), 1) != 0){
        WhatsNewDialogCreator dialogCreator = new WhatsNewDialogCreator(this, sharedPref);
        dialogCreator.show();
    }

    request = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
            .setSmallestDisplacement(0)
            .setFastestInterval(1 * 60 * 1000)
            .setInterval(60 * 60 * 1000);
    locationProvider = new ReactiveLocationProvider(this);
    //subscribe for background location updates...
    if(isNetworkAvailable()) {
        startBackgroundUpdates();
    }



    if(isFirstTimeLaunchingTheApp) {
        Log.d(TAG, "onCreate getLocation");
        getLocation();
    }
}

private void startBackgroundUpdates() {
    subscription = locationProvider.getUpdatedLocation(request)
            .subscribe(new Action1<Location>() {
                @Override
                public void call(Location location) {
                    Log.d(TAG, "Getting Background updates...");
                    MainActivity.this.latitude = location.getLatitude();
                    MainActivity.this.longitude = location.getLongitude();
                    numOfBackgroundUpdates++;

                    reverseGeocodeObservable = locationProvider
                            .getReverseGeocodeObservable(location.getLatitude(), location.getLongitude(), 1);
                    getLocationName();

                }
            });
}

@Override
protected void onPause() {
    super.onPause();
    /*
    * check if onCreate there was no internet, thus = subscription == null...
    * start the background updates onPause if there is internet
    */
    if (subscription == null && isNetworkAvailable()){
        Log.d(TAG,"startBackgroundUpdates on Pause...");
        startBackgroundUpdates();
    }
}
like image 233
Georgi Koemdzhiev Avatar asked Dec 29 '15 22:12

Georgi Koemdzhiev


People also ask

How will you handle error in RxJava?

Here, in the above code we see as soon as we get an exception in map operator and then we directly goto onError and the onNext doesn't get called or even onComplete. So, to handle the error in cases like this we use different operators and it will not move to onError directly. Let us understand them one by one.

What is onNext in RxJava?

onNext(): This method is called when a new item is emitted from the Observable. onError(): This method is called when an error occurs and the emission of data is not successfully completed. onComplete(): This method is called when the Observable has successfully completed emitting all items.

What is onErrorResumeNext RxJava?

RxJava implements the Catch operator with three distinct operators: onErrorReturn. instructs an Observable to emit a particular item when it encounters an error, and then terminate normally. onErrorResumeNext. instructs an Observable to begin emitting a second Observable sequence if it encounters an error.


1 Answers

There is an error happening when you are trying to geocode the location.

Caused by: java.io.IOException: Timed out waiting for response from server at android.location.Geocoder.getFromLocation(Geocoder.java:136)

When you call subscribe with one Action1 as a parameter it only handles calls to onNext and if an error happens the app will crash.

You need to subscribe with:

subscribe(new Subscriber<Location>() {
    @Override
    public void onNext(Location location) { /*Handle the location updates*/ }

    @Override
    public void onCompleted() { }

    @Override
    public void onError(Throwable e) { }
})
like image 198
LordRaydenMK Avatar answered Oct 19 '22 23:10

LordRaydenMK