在RxJava中自定义API异常后强制请求重试

时间:2014-11-13 21:57:12

标签: android retrofit rx-java

我在RxJava中真的很新,但我尝试使用Retrofit框架和RxJava来实现API。 在服务器端,存在处理用户会话的授权服务,并且在用户的动作中有一些延迟的情况下,服务器中断他的会话。之后,用户必须再次登录才能执行新的API调用。不好的是 - 服务器总是返回HTTP代码200,并且有关到期的通知使用带有到期代码的一些自定义JSON响应,因此RxJava在onNext操作期间不会触发异常,因为RxJava认为请求已成功通过。

问题是:如何实现正确的流程来处理自定义API异常,例如到期,并在其他一些请求后重试失败的请求(在我的情况下重新登录)?

这样的事情:

  • app - >登录()
  • 服务器 - > {code:0,...}
  • app - > getUsers()
  • 服务器 - > {code:0,...}
  • -------在30分钟内-------
  • app - > Getpicture中()
  • 服务器 - > {code:99,...} //会话已过期,未经授权的用户
  • app - >登录()
  • 服务器 - > {code:0,...}
  • app - > Getpicture中()
  • 服务器 - > {code:0,...}

我在考虑这样的事情,但没有成功:

        Observable.create(new Observable.OnSubscribe<BackendResponse<String>>() {
        @Override
        public void call(Subscriber<? super Response<String>> subscriber) {
            try {
                Response<String> response;
                subscriber.onNext(response = getInterface().getUsers());

                if (response != null) {
                  response.checkData(); // throws ServerException in case of code != 0
                }
                subscriber.onCompleted();
            } catch (Exception e) {
                subscriber.onError(e);
            }
        }
    }).subscribeOn(Schedulers.io()).retryWhen(new RetryWithSessionRefresh(new SessionService())).subscribe();

和RetryWithSessionRefresh是:

public class RetryWithSessionRefresh implements
    Func1<Observable<? extends Notification<?>>, Observable<?>> {

private final SessionService sessionSerivce;

public RetryWithSessionRefresh(SessionService sessionSerivce) {
    this.sessionSerivce = sessionSerivce;
}

@Override
public Observable<?> call(Observable<? extends Notification<?>> attempts) {
    return attempts
            .flatMap(new Func1<Notification<?>, Observable<?>>() {
                @Override
                public Observable<?> call(final Notification notification) {
                    final Throwable throwable = notification.getThrowable();
                    if (throwable instanceof ServerException) {
                        final ServerException backendException = (ServerException) throwable;
                        if (backendException.getBackendErrorCode() == Response.AUTHORIZATION_FAILED) {
                            return sessionSerivce
                                    .observeSessionToken()
                                    .doOnNext(new Action1<TokenCallback>() {
                                        @Override
                                        public void call(TokenCallback token) {
                                            if (token != null) {
                                                DataHolder.getInstance().setAuthToken(token.getToken());
                                            }
                                        }
                                    })
                                    .doOnError(new Action1<Throwable>() {
                                        @Override
                                        public void call(Throwable throwable) {
                                            DataHolder.getInstance().setAuthToken("");
                                        }
                                    });
                        }
                    }
                    return Observable.error(notification.getThrowable());
                }
            });
}

1 个答案:

答案 0 :(得分:0)

也许你可以flatMap你的响应,并在Observable.just(你的项目)成功的情况下返回你的observable,或者当Observable.error(你的错误)的响应无效时返回错误