Вместо того, чтобы объявлять вызов 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
РЕДАКТИРОВАТЬ: ОК, я наконец-то дошел до того, что сказал e-nouri в своем комментарии, а именно, что только коды 2xx будут onNext
. Оказывается, мы оба правы:
Если вызов объявлен так:
Observable<Response<MyResponseObject>> apiCall(@Body body);
или даже это
Observable<Response<ResponseBody>> apiCall(@Body body);
все ответы попадут в него onNext
, независимо от их кода ошибки. Это возможно, потому что все обернуто в Response
объект с помощью Retrofit.
Если, с другой стороны, вызов объявлен так:
Observable<MyResponseObject> apiCall(@Body body);
или это
Observable<ResponseBody> apiCall(@Body body);
действительно только ответы 2xx пойдут в onNext
. Все остальное будет упаковано HttpException
и отправлено по адресу onError
. Что также имеет смысл, потому что без Response
оболочки, что должно быть отправлено onNext
? Учитывая, что запрос не был успешным, единственная разумная вещь, которую нужно отправить, это null
...