【问题标题】:RxJava generic method to check error messages in subscriberRxJava 通用方法检查订阅者中的错误消息
【发布时间】:2016-02-09 17:20:20
【问题描述】:

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

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

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

首先我考虑使用OkHttpInterceptor,但是因为我需要将结果解析为正确的格式,所以我不能使用它。 我在解析结果后使用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
                        }

我不确定如何在此处继续,是否有类似Transformer 的东西可用于订阅以验证结果并可能启动另一个网络请求,或者在到达订阅者之前启动它会更好吗?我还在想如果 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
                })

【问题讨论】:

    标签: android generics rx-java


    【解决方案1】:

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

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

    基本思想是将Transformer 函数应用于observable,该函数在每个项目上调用doOnNext,检查错误代码并抛出适当的异常。在我的示例中,它被包装到静态帮助器类 Utils 中,但这取决于您的要求,Transformer 函数可以通过 Dagger 注入并替换为测试转换函数。

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

    【讨论】:

    • 感谢您的回复,我会立即尝试:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    相关资源
    最近更新 更多