2015-07-17 3 views
31

Я получаю ошибку IllegalStateException в Rx-библиотеке и не знаю точно, где корень проблемы, будь то с RxJava или что-то, что я могу делать неправильно.RxJava: Ошибка при попытке распространения ошибки в Observer.onError

Неустранимая авария происходит при прикреплении сертификата (происходит на всех запросах сервера), но, похоже, указывает на тайм-аут сеанса или выход из системы и обратно. Шаги Repro (около 25% времени) выглядят следующим образом: login, open элемент списка - прокрутить весь конец - выйти из системы - войти в систему - открыть приложение - закрыть приложение -> Сбой!

У кого-нибудь есть идеи о том, как предотвратить это? Я нашел подобный вопрос здесь Observer.onError firing off inconsistently

java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4867) 
    at java.lang.reflect.Method.invokeNative(Method.java) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) 
    at dalvik.system.NativeStart.main(NativeStart.java) 
Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError 
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201) 
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111) 
    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:159) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4867) 
    at java.lang.reflect.Method.invokeNative(Method.java) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) 
    at dalvik.system.NativeStart.main(NativeStart.java) 
Caused by: rx.exceptions.CompositeException: 2 exceptions occurred. 
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201) 
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111) 
    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:159) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4867) 
    at java.lang.reflect.Method.invokeNative(Method.java) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) 
    at dalvik.system.NativeStart.main(NativeStart.java) 
Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => 
    at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:597) 
    at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600) 
    at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600) 
    at com.crashlytics.android.SessionDataWriter.getEventAppExecutionSize(SessionDataWriter.java:533) 
    at com.crashlytics.android.SessionDataWriter.getEventAppSize(SessionDataWriter.java:492) 
    at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.writeSessionEvent(CrashlyticsUncaughtExceptionHandler.java:956) 
    at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.access$200(CrashlyticsUncaughtExceptionHandler.java:56) 
    at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler$7.call(CrashlyticsUncaughtExceptionHandler.java:274) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
    at io.fabric.sdk.android.services.common.ExecutorUtils$1$1.onRun(ExecutorUtils.java:58) 
    at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:13) 
    at java.lang.Thread.run(Thread.java:856) 
+0

Hi Scott. Любая возможность узнать версию Android, версию RxJava, версию RxAndroid, пожалуйста? Вы правильно распоряжаетесь всеми своими подписками? –

+0

io.reactivex: rxandroid: 0.24.0 io.reactivex: rxjava: 1.0.12 'Android версии 5.1' И да я отпиской все мои подписки, а затем settineg их обнулить –

+0

Вы можете попробовать RxAndroid 1.0.1https : //github.com/ReactiveX/RxAndroid/releases/tag/v1.0.1 пожалуйста? –

ответ

39

То, что происходит в том, что ваш onError реализация в Subscriber бросает непроверенное исключение, которое против Наблюдаемого договор, и это ликвидирует наблюдаемую обработку выбрасывания OnErrorFailedException в observeOn планировщика.

+0

Стоит отметить, что если вы попытаетесь отладить это, войдя в вашу реализацию 'onError', вы можете не увидеть ее в logcat. Вы лучше всего отлаживаете точки останова. Это то, что мешало мне сначала увидеть проблему. – tir38

+0

Как я могу отслеживать точную ошибку в обратном вызове 'onError()' вместо получения этой общей stacktrace? – Lemberg

+0

Как это исправить? –

10

Возможно, вы передаете контекст активности где-то из вашего обратного вызова onError. Это происходило со мной, когда я пытался показать AlertDialog - передав ему конкретный контекст активности - и нажав кнопку «Назад» до появления этого диалогового окна. Мой совет - не передавать контексты активности таким образом.

+1

это звучит скорее как очень конкретный случай – carlosavoy

+0

@ CarloLópezScutaro Что вызывает у вас проблема? –

+0

Это случилось со мной. Точный такой же сценарий. Как вы создали диалог? Я создаю свое диалоговое создание, отвлеченное на класс util, поэтому мне нужно передать ему контекст для создания AlertDialog. – Brandon

-1

если вы хотите обновить пользовательский интерфейс в OnError, просто попробуйте:

api.subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber(){....}) 
0

Это, как я решил эту проблему:

public abstract class MyNetworkSubscriber<T> extends Subscriber<T> { 

@Override 
public void onCompleted() {} 

@Override 
public void onError(Throwable e) { 
    if (e instanceof HttpException) { 
     ResponseBody responseBody = ((HttpException) e).response().errorBody(); 
     try { 
      if (responseBody != null) { 
       MyError error = new Gson().fromJson(responseBody.string(), MyError.class); 
       onErrorCode(error); 
      } 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } 
    } else { 
     e.printStackTrace(); 
    } 
} 

public void onErrorCode(MyError error){}; 
} 

По какой-то причине, OkHttp заставляла меня поймать OnError так я сделал. Если я этого не сделаю, OkHttp/Retrofit выйдет из строя, и приложение отключится.

Предоставляя это решение,

  1. вы можете переопределить свой собственный onErrorCode и получить более подробную объект назад как ошибка, которая исходит от вашего API, но вы не должны.
  2. OnError переопределен, больше нет сумасшедших сбоев.
  3. И последнее, но не менее важное - это все-таки общее из-за <T>!

Вы также можете заставить onComplete & onError быть переопределенным, чтобы сделать абстрактные методы.

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