在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?
}
});
答案 0 :(得分:4)
这取决于您的配置,部分取决于您如何定义通话,但它将归结为2 Observables
中的一个。
如果查看源代码,您可以看到,如果您的通话返回Response<Foo>
类型,则会在内部为您的通话创建CallEnqueueObservable<Foo>
或CallExecuteObservable
。请在adapt方法中查看。对于RxJava 1,这是类似的,但是可观察的是不同的。无论如何,内部的工作方式是完全相同的。执行调用并使用onNext
实例调用response
。
如果您在Retrofit
的代理机制中查看其工作方式,即使响应是Http错误,也始终会有response
个实例。这意味着即使响应本身就是http错误,调用onNext
仍然会发生。您可以查看parseReponse方法,如果状态代码为500,则不会抛出任何异常。
返回观察者,只有在有例外时才会调用订阅者onError
。请记住,如果它的状态代码为500,则不会抛出任何异常。
要使onError
触发非2XX http错误代码,有不同的方法,但一种可能的方法是(如果你能负担得起)让你的电话返回Observable<Foo>
而不是{{ 1}}。
这将使内部使用不同的可观察内容进行改造,以确保在出现http错误和异常时致电您的订阅者Observable<Response<Foo>>
。
答案 1 :(得分:1)
只有网络错误会被投入onError
(例如没有互联网连接)。
将500er视为来自服务器的有效响应,而不是错误情况。此外,您希望使用服务器提供的错误信息(正文,状态代码,标题等)。 onError
无法提供此功能(除非作为例外)。