Anstatt den API-Aufruf wie folgt zu deklarieren:
Observable<MyResponseObject> apiCall(@Body body);
Sie können es auch so deklarieren:
Observable<Response<MyResponseObject>> apiCall(@Body body);
Sie haben dann einen Abonnenten wie den folgenden:
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!
}
}
Serverantworten mit einem Fehlercode werden also auch an gesendet, onNext
und Sie können den Code durch Aufrufen abrufen reponse.code()
.
http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html
EDIT: OK, ich habe mich endlich damit beschäftigt, zu untersuchen, was e-nouri in ihrem Kommentar gesagt hat, nämlich dass nur 2xx Codes dazu gehören onNext
. Es stellt sich heraus, dass wir beide Recht haben:
Wenn der Anruf wie folgt deklariert ist:
Observable<Response<MyResponseObject>> apiCall(@Body body);
oder sogar das
Observable<Response<ResponseBody>> apiCall(@Body body);
Alle Antworten werden onNext
unabhängig von ihrem Fehlercode angezeigt. Dies ist möglich, weil alles Response
von Retrofit in ein Objekt eingewickelt wird.
Wenn andererseits der Anruf wie folgt deklariert wird:
Observable<MyResponseObject> apiCall(@Body body);
oder dieses
Observable<ResponseBody> apiCall(@Body body);
in der Tat werden nur die 2xx Antworten gehen onNext
. Alles andere wird in ein verpackt HttpException
und an gesendet onError
. Was macht auch Sinn, denn Response
was soll ohne Wrapper ausgegeben werden onNext
? Da die Anfrage nicht erfolgreich war, wäre es nur sinnvoll, null
...