Em vez de declarar a chamada da API como você fez:
Observable<MyResponseObject> apiCall(@Body body);
Você também pode declará-lo assim:
Observable<Response<MyResponseObject>> apiCall(@Body body);
Você terá então um Assinante como o seguinte:
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!
}
}
Portanto, as respostas do servidor com um código de erro também serão entregues onNext
e você pode obter o código chamando reponse.code()
.
http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html
EDIT: OK, finalmente consegui analisar o que o e-nouri disse em seu comentário, ou seja, que apenas os códigos 2xx o farão onNext
. Acontece que ambos estamos certos:
Se a chamada for declarada assim:
Observable<Response<MyResponseObject>> apiCall(@Body body);
ou mesmo isso
Observable<Response<ResponseBody>> apiCall(@Body body);
todas as respostas terminarão em onNext
, independentemente do código de erro. Isso é possível porque tudo está embrulhado em um Response
objeto pelo Retrofit.
Se, por outro lado, a chamada for declarada assim:
Observable<MyResponseObject> apiCall(@Body body);
ou isto
Observable<ResponseBody> apiCall(@Body body);
na verdade, apenas as respostas 2xx irão onNext
. Todo o resto será embrulhado em HttpException
e enviado para onError
. O que também faz sentido, porque sem o Response
invólucro, o que deve ser emitido onNext
? Dado que o pedido não foi bem sucedido, a única coisa sensata a emitir seria null
...
onNext
incluindo 404, etc. Usei Retrofit v2.0.0-beta3.GsonConverterFactory
, assim comoRetrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
, Como obter a resposta original?Response
. Também raramente o uso - mas acho bom saber que existe.Dentro do método onError coloque-o para obter o código
fonte
HttpException
. Estou usando o RxJava e precisei analisar a resposta depois de receber umHTTP 400 BAD REQUEST
. Muito obrigado!Você deve notar que a partir do Retrofit2 todas as respostas com o código 2xx serão chamadas de retorno de chamada onNext () e o resto dos códigos HTTP como 4xx, 5xx serão chamados no retorno de chamada onError () , usando Kotlin. Eu vim com algo como isso no onError () :
fonte