使用Obtrables with Retrofit时如何处理网络故障?
鉴于此代码:
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浮出水面?
答案 0 :(得分:33)
我的问题实际上是我的代码中的其他地方。使用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
}
}
}
答案 1 :(得分:12)
这纯粹是一个RxJava问题,并没有涉及Retrofit那么多。 doOnError
是副作用,所以即使它处理错误,它也不会捕获&#34;在防止它向前冒泡的意义上。
你应该看看Error Handling Operators。最基本的选项是onErrorReturn()
,它允许您将错误替换为项目(GetJobResponse
的实例)。
你可以输入一个&#34;错误&#34;标记该项目,以便稍后在您订阅observable
时识别它。同样重要的是要知道,如果你没有订阅这个可观察者,那么它基本上就已经死了#34;你应该总是订阅observable而不是使用&#34; doOn ___&#34;这只是副作用(应该用于记录和其他非关键功能)。
答案 2 :(得分:0)
请注意,如果您让一个observable发出onError
,则所有上游可观察对象都将关闭 - 无论您是否使用onErrorReturn
或onErrorResumeNext
“捕获”它。通常你不希望这样。例如,如果您的流以点击按钮开始,触发了一个失败的改装请求,那么自流终止后,按钮点击将不再被识别。
使用Observable<Response<Type>>
或Observable<Result<Type>>
处理onNext()
中的改造错误。
秒。 http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/
答案 3 :(得分:0)
自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
}
}