Замість того, щоб оголошувати виклик 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
...