问题描述
在android上,我通过改造进行服务器调用,服务器有时可以返回500响应。
为什么没有在订阅者中调用onError的原因?
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response<Void>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (isViewAttached()) {
getView().onError(e);
}
}
@Override
public void onNext(Response<Void> response) {
response.code() <-- why would 500 here not get routed to the onError instead?
}
});
1楼
这部分取决于您的配置以及部分如何定义调用,但这全都归结为2个Observables
。
如果您查看源代码,则可以看到,如果您的呼叫返回了Response<Foo>
类型, CallEnqueueObservable<Foo>
将在内部为您的呼叫创建CallEnqueueObservable<Foo>
或CallExecuteObservable
。
用方法检查一下。
对于RxJava 1,这是相似的,但可观察对象的调用方式有所不同。
无论如何,内部工作方式完全相同。
执行该调用,并使用response
实例调用onNext
。
如果您看一下Retrofit
的代理机制中的工作原理,即使响应是Http错误,也将始终有一个response
实例。
这意味着即使响应本身是http错误,仍然会继续调用onNext
。
您可以看一下方法,并且看到状态码为500时不会抛出异常。
返回到可观察对象,只有在发生异常时,才会调用订户的onError
。
请记住,如果状态码为500,则不会引发任何异常。
要使onError
触发非2XX http错误代码,可以采用不同的方法,但是一种可能的方法是(如果可以承受的话)使调用返回Observable<Foo>
而不是Observable<Response<Foo>>
。
这将使内部使用不同的可观察变量进行改进,这些可观察变量将确保在出现http错误和异常时调用订户的onError
。
2楼
仅将网络错误引发到onError
(例如,没有Internet连接)。
将500er视为来自服务器的有效响应,而不是错误情况。
此外,您还想使用服务器提供的错误信息(正文,状态代码,标题等)。
onError
无法提供此功能(除非作为例外)。