android - RxJava: Se produjo un error al intentar propagar el error a Observer.onError
exception rx-java (4)
Así es como resolví el problema:
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){};
}
Por alguna razón, OkHttp me estaba obligando a detectar el error, así que lo hice. Si no hice esto, OkHttp / Retrofit se bloqueará y la aplicación se apagará.
Al proporcionar esta solución,
- puede elegir anular su propio
onErrorCode
y recuperar un objeto más detallado como un error que proviene de su API, pero no es necesario. - OnError está anulado, no más accidentes locos.
- ¡Y por último, pero no menos importante, sigue siendo genérico debido a
<T>
!
También puede forzar que se omita onComplete & onError para que los métodos sean abstractos.
Recibo un error de IllegalStateException en la Biblioteca de Rx y no sé exactamente dónde está la raíz del problema, ya sea con RxJava o algo que pueda estar haciendo incorrectamente.
El bloqueo fatal ocurre cuando se realiza la fijación del certificado (ocurre en todas las solicitudes del servidor) pero parece apuntar a un tiempo de espera de sesión o cerrar la sesión. Los pasos de reprografía (aproximadamente el 25% del tiempo) son los siguientes: inicio de sesión, abrir elemento de lista hasta el final - cerrar sesión - iniciar sesión en - abrir aplicación - cerrar aplicación -> ¡Crash!
¿Alguien tiene alguna idea sobre cómo prevenir esto? Encontré un problema similar aquí Observer.onError disparando de forma inconsistente
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)
Lo que está sucediendo es que su implementación onError
en un Subscriber
está lanzando una excepción no verificada que está en contra del contrato de Observable y esto anula el procesamiento observable lanzando una OnErrorFailedException
en el scheduler observeOn
.
Probablemente esté pasando un contexto de actividad en algún lugar desde su onError
llamada onError
. Esto me estaba sucediendo cuando traté de mostrar un AlertDialog, pasándole un contexto de actividad específico, y presionar el botón Atrás antes de que surgiera ese diálogo. Mi consejo es no pasar los contextos de actividad de esta manera.
si quieres actualizar la interfaz de usuario en onError, simplemente prueba:
api.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber(){....})