Вместо того, чтобы объявлять вызов 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...