rxjava mvc example ejemplo android retrofit rx-java

example - retrofit mvc android



reacondicionamiento con rxjava manejando excepciones de red globalmente (2)

onErrorResumeNext(Func1 resumeFunction) utilizar el operador onErrorResumeNext(Func1 resumeFunction) , mejor explicado en la wiki oficial :

El método onErrorResumeNext () devuelve un Observable que refleja el comportamiento de la fuente Observable, a menos que ese Observable invoque onError () en ese caso, en lugar de propagar ese error al Suscriptor, onErrorResumeNext () comenzará a duplicar un segundo, Observable

En tu caso me gustaría poner algo como esto:

getCurrentUser = userApi.getCurrentUser() .onErrorResumeNext(refreshTokenAndRetry(userApi.getCurrentUser())) .observeOn(AndroidSchedulers.mainThread()) .subscribe(...)

dónde:

private <T> Func1<Throwable,? extends Observable<? extends T>> refreshTokenAndRetry(final Observable<T> toBeResumed) { return new Func1<Throwable, Observable<? extends T>>() { @Override public Observable<? extends T> call(Throwable throwable) { // Here check if the error thrown really is a 401 if (isHttp401Error(throwable)) { return refreshToken().flatMap(new Func1<AuthToken, Observable<? extends T>>() { @Override public Observable<? extends T> call(AuthToken token) { return toBeResumed; } }); } // re-throw this error because it''s not recoverable from here return Observable.error(throwable); } }; }

Tenga en cuenta también que esta función se puede usar fácilmente en otros casos, ya que no está escrita con los valores reales emitidos por el Observable reanudado.

Estoy tratando de manejar las excepciones en la aplicación a nivel global, por lo que la modificación produce un error, lo detecto en alguna clase específica con lógica para manejar esos errores.

Tengo una interfaz

@POST("/token") AuthToken refreshToken(@Field("grant_type") String grantType, @Field("refresh_token") String refreshToken);

y observables

/** * Refreshes auth token * * @param refreshToken * @return */ public Observable<AuthToken> refreshToken(String refreshToken) { return Observable.create((Subscriber<? super AuthToken> subscriber) -> { try { subscriber.onNext(apiManager.refreshToken(REFRESH_TOKEN, refreshToken)); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }).subscribeOn(Schedulers.io()); }

Cuando recibo el 401 del servidor (token no válido o algún otro error relacionado con la red) quiero actualizar el token y repetir la llamada de resto. ¿Hay una manera de hacer esto con rxjava para todas las llamadas de descanso con algún tipo de observable que detecte este error globalmente, lo maneje y repita la llamada que lo lanzó?

Por ahora estoy usando un asunto para detectar el error en .subscribe () como este

private static BehaviorSubject errorEvent = BehaviorSubject.create(); public static BehaviorSubject<RetrofitError> getErrorEvent() { return errorEvent; }

y en alguna llamada

getCurrentUser = userApi.getCurrentUser().observeOn(AndroidSchedulers.mainThread()) .subscribe( (user) -> { this.user = user; }, errorEvent::onNext );

luego en mi actividad principal me suscribo a ese tema de comportamiento y analizo el error

SomeApi.getErrorEvent().subscribe( (e) -> { //parse the error } );

pero no puedo repetir la llamada para el observable que arroja el error.


@Override public Observable<List<MessageEntity>> messages(String accountId, int messageType) { return mMessageService.getLikeMessages(messageType) .onErrorResumeNext(mTokenTrick. refreshTokenAndRetry(mMessageService.getLikeMessages(messageType))); }