Необработанное исключение внутри onNext распространяется в глобальный обработчик исключений RxJava - PullRequest
0 голосов
/ 03 декабря 2018

Ниже приведен упрощенный пример проблемы, которую я пытаюсь решить.В моей базе кода проблема возникает с PublishSubject, но Observable может использоваться для воспроизведения этой проблемы.

Проблема:

У меня есть необдуманное исключение в onNext() подписчика, который передает исключение в глобальный обработчик исключений RxJava, что приводит к сбою.Однако это не желаемое поведение.Цель состоит в том, чтобы корректно обработать необработанные исключения.

Вопрос:

Почему onError() не вызывается для необработанного исключения?Какой метод (ы) я могу использовать, чтобы поймать такие необъяснимые исключения?

Быстрое решение:

Я могу использовать RxJavaPlugins.setErrorHandler, чтобы справиться с этой ситуацией, но я бы хотеллучше использовать это решение как последнее средство, если у нас нет другого решения для решения проблемы.

Код:

Observable.just(true)
                .subscribeWith(new DisposableObserver<Boolean>() {
                    @Override
                    public void onNext(Boolean aBoolean) {
                        String x = null;
                        x.getBytes();
                    }

                    @Override
                    public void onError(Throwable e) { <--- NOT CALLED UPON EXCEPTION
                        System.out.println("inside test observable onError");
                        e.printStackTrace();
                    }

                    @Override
                    public void onComplete() {

                    }
                });

Stacktrace:

12-03 11:09:01.454 4750-4750/? E/MDMApplication: UNCAUGHT EXCEPTION IN APP: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.mdm.app/mdm.connector.app.MainActivity}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
        at mdm.connector.app.MainActivity$1.onNext(MainActivity.java:63)
        at mdm.connector.app.MainActivity$1.onNext(MainActivity.java:59)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:103)
        at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:64)
        at io.reactivex.internal.operators.observable.ObservableScalarXMap$ScalarDisposable.run(ObservableScalarXMap.java:248)
        at io.reactivex.internal.operators.observable.ObservableJust.subscribeActual(ObservableJust.java:35)
        at io.reactivex.Observable.subscribe(Observable.java:12036)
        at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
        at io.reactivex.Observable.subscribe(Observable.java:12036)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach.subscribeActual(ObservableDoOnEach.java:42)
        at io.reactivex.Observable.subscribe(Observable.java:12036)
        at io.reactivex.Observable.subscribeWith(Observable.java:12088)
        at mdm.connector.app.MainActivity.onCreate(MainActivity.java:59)
        at android.app.Activity.performCreate(Activity.java:5231)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
        at android.app.ActivityThread.access$800(ActivityThread.java:135) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:136) 
        at android.app.ActivityThread.main(ActivityThread.java:5017) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:515) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
        at dalvik.system.NativeStart.main(Native Method) 

1 Ответ

0 голосов
/ 03 декабря 2018

Решение вышеуказанной проблемы состоит в том, что вместо использования DisposableObserver мы должны использовать Consumer & Consumer в методе подписки.Это гарантирует, что если в методе приема Consumer есть какие-либо неперехваченные исключения, они будут перехвачены в методе приема Consumer вместо того, чтобы распространяться на глобальный обработчик исключений RxJava, что приведет к сбою.

Пример:

Observable.just(true)
.subscribe(new Consumer<Boolean> {
  public void accept(Boolean aboolean) {
      String x = null;
      x.getBytes();
  }
}, new Consumer<Throwable> {

  public void accept(Throwable e) {
      e.printStackTrace()
  }
});

Если есть другое лучшее решение для обработки необработанных исключений, пожалуйста, укажите это в комментариях

...