在 RxJava 中自定义 API 异常后强制请求重试 [英] Forcing request retry after custom API exceptions in RxJava

查看:58
本文介绍了在 RxJava 中自定义 API 异常后强制请求重试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm really new in RxJava, but I'm trying to implement an API using Retrofit framework and RxJava. On a server side there is an authorization service which handles user's session and in case of some delay in user's actions server breaks his session. After that user has to login again in order to perform new API call. Bad thing is - server always returns HTTP code 200 and for notification about expiration uses some custom JSON response with expiration code, so RxJava doesn't fire Exception during onNext operation because RxJava considers that request was passed successfully.

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

And the question is: How to implement correct flow to handle custom API exceptions like expiration and retry failed request after some other request (in my case relogin)?

像这样:

  • 应用程序 -> 登录()
  • 服务器 -> { code:0, ... }
  • app -> getUsers()
  • 服务器 -> { code:0, ... }
  • ------- 30 分钟后-------
  • app -> getPicture()
  • server -> { code:99, ... }//会话过期,用户未授权
  • 应用程序 -> 登录()
  • 服务器 -> { code:0, ... }
  • app -> getPicture()
  • 服务器 -> { code:0, ... }

我正在考虑类似的事情,但没有成功:

I was thinking about something like this, but with no success:

        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 是:

and RetryWithSessionRefresh is:

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());
                }
            });
}

推荐答案

也许你 vanflapMap 你的响应,并在成功的情况下返回你的 observable.just(your item) 或者响应无效时的错误与 Observable.error(你的错误)

Maybe you van flapMap your response, and return your observable in case of success with Observable.just(your item) or an error when the response isn't valid with Observable.error(your error)

这篇关于在 RxJava 中自定义 API 异常后强制请求重试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆