当前位置: 首页 > 知识库问答 >
问题:

检查订阅服务器中错误消息的RxJava通用方法

白晋鹏
2023-03-14

在我的Android项目中,我执行了很多网络请求(使用reverfitrxjava),这些请求作为响应返回一个自定义的响应超类型,它可以由有效响应或错误响应组成。

AppResponse {  
   error=AppError {  
      code=12345,
      message='null'
   },
   data=null
}

错误代码不是HTTP错误代码,而是通过使用SimpleXML解析XML结果检索到的内容。大约有4-5个错误代码对所有网络请求都是相同的,例如会话超时。因此,我将编写一个泛型方法,检查所有响应中的错误代码,并设置对策,如请求一个新会话。

首先,我考虑使用OKHTTP拦截器,但因为我需要将结果解析为正确的格式,所以无法使用它。在解析结果之后,我正在使用rxjava,目前我正在subscribe方法中检查结果的响应。

    restClient.requestHostList()
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<HostListResponse>() {

                @Override
                public void onError() {

                }
                @Override
                public void onCompleted() {

                }

                @Override
                public void onNext(HostListResponse hostListResponse) {
                    if (hostListResponse.isError()) {

                        if(hostListResponse.getError().getCode() == 12345) {
                            requestNewSession();
                        } else if(hostListResponse.getError().getCode() == 23456) {
                            requestNewLogin();
                        }
                   else {
                            //do some UI stuff here
                        }

我不确定如何继续这里,有类似转换器的东西可以在subscribe中使用来验证结果并可能启动另一个网络请求,还是在到达订阅者之前启动它更好?我还在想,如果onErrorResumeNext()是一个选项,当Observable未通过结果代码测试时,它会抛出一个错误,如下所示:

restClient.requestHostList()
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Func1<HostListResponse, Observable<Throwable>>() {
                    @Override
                    public Observable<Throwable> call(HostListResponse hostListResponse) {
                        if (hostListResponse.isError()) {
                            if(hostListResponse.getError().getCode() == 12345) {
                                throw new Exception();
                            }
                        }
                    }
                })
                .onErrorResumeNext(new Func1<Throwable, Observable<? extends Throwable>>() {
                    //do error handling here
                })

共有1个答案

幸弘光
2023-03-14

最后一个解决方案是可以的。在错误情况下抛出异常是绝对正常的行为。您可以使用compose运算符来包装错误处理逻辑,并将其与所有可观察到的改型内容一起重用:

static final int NO_ERROR = 0;
static final int ERROR_A = 13;
static final int ERROR_B = 666;

Observable<BaseResponse> responseObservable = Observable.create(new Observable.OnSubscribe<BaseResponse>() {
    @Override
    public void call(Subscriber<? super BaseResponse> subscriber) {
        subscriber.onNext(new BaseResponse(ERROR_A));
        //subscriber.onNext(new BaseResponse(ERROR_B));
        //subscriber.onNext(new BaseResponse(NO_ERROR));
        subscriber.onCompleted();
    }
});

responseObservable
        .compose(Utils.applyErrorHandler())//apply to this observable error handling logic
        .subscribe(baseResponse -> {
            System.out.println("ok");
        }, throwable -> {
            System.out.println("error:" + throwable);
        });

处理错误的Utils类:

public static class Utils {
    static Observable.Transformer schedulersTransformer = new Observable.Transformer<BaseResponse, BaseResponse>() {
        @Override
        public Observable<BaseResponse> call(Observable<BaseResponse> observable) {
            return observable.doOnNext(baseResponse -> {
                if (baseResponse.errorCode == ERROR_A) {
                    throw new RuntimeException("Error A");
                } else if (baseResponse.errorCode == ERROR_B) {
                    throw new RuntimeException("Error B");
                }
            });
        }
    };

    @SuppressWarnings("unchecked")
    public static <T> Observable.Transformer<T, T> applyErrorHandler() {
        return (Observable.Transformer<T, T>) schedulersTransformer;
    }
}

其基本思想是对observable应用transformer函数,对每个项目调用doonnext,检查错误代码并抛出相应的异常。在我的示例中,utils被包装到静态帮助器类中,但这取决于您的需求,transformer函数可以通过dagger注入,并替换为例如测试转换函数。

您可以在Dan Lew博客文章中阅读关于compose运算符的更多信息:http://blog.danlew.net/2015/03/02/dont-break-the-chain/

 类似资料:
  • 我有一个使用ActiveMQ的JMS生产者/订阅者的简单Spring应用程序,配置如下: 我试过所有可能的解决办法,但没有一个奏效。我们非常感谢任何帮助

  • 想象一下MVP模式中的情况,演示者订阅了一个返回观察者的服务: 现在,类从视图中调用方法,比如: 现在,在我的单元测试中,我想验证在非错误情况下调用方法时,是否调用了视图的方法。 问题是: 有没有干净的方法可以做到这一点? 背景: 我使用mockito来验证交互,当然还有更多 Dagger正在注入整个演示者,除了 我试过什么: 注入订阅服务器并在测试中模拟它。看起来有点脏,因为如果我想改变演示者与

  • 主要内容:一、通知,二、源码分析,三、总结一、通知 在Redis中,既可以实现消息的发送又可以实现订阅,也就是常说的发布/订阅。它的主要逻辑实现在nofigy.c和module.c、pubsub.c中,其实通知做为一种辅助功能,是易用性的一种良好的接口。Redis的通知功能是一种即时在线通知功能,如果CS端断线后,相关的消息就无法再次通知,也就是说,消息机制没有保存和重发功能。这也是为了实现设计上的简单和功能实现的鲁棒性的考虑,至于以后会

  • 我有一个超时选项,只想在超时前接收消息。 如果您能解释下面的代码是如何工作的,以及我如何修改下面的代码以在特定的时间框架内接收消息,并且一旦我的超时已经到达就停止接收,这将是很有帮助的。

  • 微信文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.addTemplate.html 组合模板并添加至帐号下的个人模板库 $tid = 563; // 模板标题 id,可通过接口获取,也可登录小程序后台查看获取 $kidLi

  • 开普勒消息目前分为三大类:公告,告警和通知。 通知中根据不同的操作事件类型,分为十几个事件。每个事件都跟项目操作相关。便于接收项目操作变更的通知。 分类 事件 公告 Alarm 告警 Proclaim 通知 Build,Apply,Audit,Delete,Rollback,Logging,Reboot,Command,Storage,Extend... 订阅界面: 用户中心,点击头像,下拉菜单→