在Retrofit中使用Observables时,您如何处理网络故障?
给定这个代码:
Observable<GetJobResponse> observable = api.getApiService().getMyData();
observable
.doOnNext(new Action1<GetJobResponse>() {
@Override
public void call(GetJobResponse getJobResponse) {
//do stuff with my data
}
})
.doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
//do stuff with error message
}
});
请求在没有网络的情况下失败,并且没有调用onError。它不会崩溃,而是无声地失败。日志显示Retrofit得到错误:
java.net.UnknownHostException: Unable to resolve host "api-staging.sittercity.com": No address associated with hostname
at java.net.InetAddress.lookupHostByName(InetAddress.java:424)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at com.squareup.okhttp.internal.Dns$1.getAllByName(Dns.java:29)
使用回调,这只是传递给onFailure(RetrofitError错误)。如何在RxJava中实现这一点?
我的问题实际上在我的代码的其他地方。使用rxJava + Retrofit处理网络错误非常简单,因为它只是在onError方法中抛出RetrofitError:
@Override
public void onError(Throwable e) {
if (e instanceof RetrofitError) {
if (((RetrofitError) e).isNetworkError()) {
//handle network error
} else {
//handle error message from server
}
}
}
这纯粹是RxJava问题,与Retrofit没有太大关系。doOnError
是一个副作用,所以即使它处理错误,它也不会"捕获"它阻止它向前冒泡。
您应该查看错误处理操作符。最基本的选项是onErrorReturn()
,它允许您用项目(GetJobResponse
的实例)替换错误。
您可以在该项目上放置一个"错误"标志,以便在以后订阅observable
时识别它。同样重要的是要知道,如果你不订阅那个可观察对象,它本质上是"死亡"的。您应该始终订阅可观察对象,而不是使用"doOn___",这只是副作用(应该用于日志记录和其他非关键功能)。
注意,如果你让一个可观察对象发出onError
,所有上游的可观察对象都会关闭——不管你是用onErrorReturn
还是onErrorResumeNext
"捕获"它。通常你不希望这样。例如,如果你的流以点击按钮开始,触发了一个失败的改造请求,那么点击按钮将不再被识别,因为流终止了。
使用Observable<Response<Type>>
或Observable<Result<Type>>
也可以处理onNext()
中的改造错误。
。http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/
从Retrofit2
和RxJava2
开始,不再有RetrofitError
例外。它的后继HttpException
只表示HTTP错误响应码。网络错误应通过IOException
处理。
@Override
public void onError(Throwable e) {
if (e instanceof IOException) {
//handle network error
} else if (e instanceof HttpException) {
//handle HTTP error response code
} else {
//handle other exceptions
}
}