Замість того, щоб оголошувати виклик 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
РЕДАКТ: Добре, я нарешті розібрався з тим, що сказав е-нурі у своєму коментарі, а саме, що лише 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...