【问题标题】:Forcing request retry after custom API exceptions in RxJava在 RxJava 中自定义 API 异常后强制请求重试
【发布时间】:2015-01-11 04:57:57
【问题描述】:

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

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

类似这样的:

  • 应用程序->登录()
  • 服务器 -> { 代码:0, ... }
  • 应用程序-> getUsers()
  • 服务器 -> { 代码:0, ... }
  • ------- 30 分钟后 -------
  • 应用程序->getPicture()
  • server -> { code:99, ... } // 会话过期,用户未授权
  • 应用程序->登录()
  • 服务器 -> { 代码:0, ... }
  • 应用程序->getPicture()
  • 服务器 -> { 代码: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());
                }
            });
}

【问题讨论】:

    标签: android retrofit rx-java


    【解决方案1】:

    也许你用翻盖映射你的响应,并在 Observable.just(your item) 成功的情况下返回你的 observable,或者当响应对 Observable.error(your error) 无效时返回一个错误

    【讨论】:

      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 2013-11-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多