而不是像您那样声明 API 调用:
Observable<MyResponseObject> apiCall(@Body body);
您也可以这样声明:
Observable<Response<MyResponseObject>> apiCall(@Body body);
然后您将拥有一个如下所示的订阅者:
new Subscriber<Response<StartupResponse>>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {
Timber.e(e, "onError: %", e.toString());
// network errors, e. g. UnknownHostException, will end up here
}
@Override
public void onNext(Response<StartupResponse> startupResponseResponse) {
Timber.d("onNext: %s", startupResponseResponse.code());
// HTTP errors, e. g. 404, will end up here!
}
}
因此,带有错误代码的服务器响应也将被传递到onNext
您可以通过调用获取代码reponse.code()
.
http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html
EDIT:好的,我终于开始研究 e-nouri 在他们的评论中所说的内容,即只有 2xx 代码才能onNext
。事实证明我们都是对的:
如果调用是这样声明的:
Observable<Response<MyResponseObject>> apiCall(@Body body);
甚至这个
Observable<Response<ResponseBody>> apiCall(@Body body);
all回应将最终在onNext
,无论其错误代码如何。这是可能的,因为一切都包裹在Response
改造对象。
另一方面,如果调用声明如下:
Observable<MyResponseObject> apiCall(@Body body);
or this
Observable<ResponseBody> apiCall(@Body body);
实际上只有 2xx 响应会发送到onNext
。其他一切都将被包裹在一个HttpException
并发送至onError
。这也是有道理的,因为如果没有Response
包装纸,什么should被发射到onNext
?鉴于请求未成功,发出的唯一明智的事情是null
...