在我的Android
项目中,我做了很多网络请求(使用Retrofit
和RxJava
),它们作为响应返回一个自定义的超类型响应,它可以包含一个有效的或错误回复。
AppResponse {
error=AppError {
code=12345,
message='null'
},
data=null
}
错误代码不是HTTP错误代码,而是使用XML
解析SimpleXML
结果时检索到的内容。对于所有网络请求,大约有4-5个错误代码是相同的,例如会话超时等。因此,我想编写一个通用方法来检查这些错误代码的所有响应,并设置诸如请求新会话之类的对策。
首先我考虑使用OkHttp
拦截器,但因为我需要将结果解析为正确的格式,所以我无法使用它。
我在解析结果后使用RxJava
,目前我正在检查我的结果在订阅方法中的响应。
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
})
答案 0 :(得分:2)
最后的解决方案还可以。在错误情况下抛出异常是绝对正常的行为。您可以使用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
注入,并替换为例如测试转换函数。
您可以在compose
博文中详细了解Dan Lew
运算符:http://blog.danlew.net/2015/03/02/dont-break-the-chain/