example - android retrofit rxjava
Obtenga el código de estado de respuesta usando Retrofit 2.0 y RxJava (3)
Debe tener en cuenta que a partir de Retrofit2 todas las respuestas con el código 2xx se llamarán desde la devolución de llamada onNext () y el resto de los códigos HTTP como 4xx, 5xx se llamarán en la devolución de llamada onError () , usando Kotlin se me ocurrió algo como esto en el onError () :
mViewReference?.get()?.onMediaFetchFinished(downloadArg)
if (it is HttpException) {
val errorCode = it.code()
mViewReference?.get()?.onMediaFetchFailed(downloadArg,when(errorCode){
HttpURLConnection.HTTP_NOT_FOUND -> R.string.check_is_private
else -> ErrorHandler.parseError(it)
})
} else {
mViewReference?.get()?.onMediaFetchFailed(downloadArg, ErrorHandler.parseError(it))
}
Estoy tratando de actualizar a Retrofit 2.0 y agregar RxJava en mi proyecto de Android. Estoy haciendo una llamada a la API y quiero recuperar el código de error en caso de una respuesta de error del servidor.
Observable<MyResponseObject> apiCall(@Body body);
Y en la llamada RxJava:
myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MyResponseObject myResponseObject) {
//On response from server
}
});
En Retrofit 1.9, el RetrofitError todavía existía y podríamos obtener el estado haciendo:
error.getResponse().getStatus()
¿Cómo se hace esto con Retrofit 2.0 usando RxJava?
Dentro del método onError puesto a esto, obtenga el código
((HttpException) e).code()
En lugar de declarar la llamada API como lo hiciste:
Observable<MyResponseObject> apiCall(@Body body);
También puedes declararlo así:
Observable<Response<MyResponseObject>> apiCall(@Body body);
Entonces tendrá un suscriptor como el siguiente:
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!
}
}
Por lo tanto, las respuestas del servidor con un código de error también se
onNext
a
onNext
y puede obtener el código llamando a
reponse.code()
.
http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html
EDITAR:
OK, finalmente pude analizar lo que dijo e-nouri en su comentario, es decir, que solo los códigos 2xx lo harán en
onNext
.
Resulta que ambos tenemos razón:
Si la llamada se declara así:
Observable<Response<MyResponseObject>> apiCall(@Body body);
o incluso esto
Observable<Response<ResponseBody>> apiCall(@Body body);
todas las
respuestas terminarán en
onNext
, independientemente de su código de error.
Esto es posible porque Retrofit envuelve todo en un objeto de
Response
.
Si, por otro lado, la llamada se declara así:
Observable<MyResponseObject> apiCall(@Body body);
o esto
Observable<ResponseBody> apiCall(@Body body);
de hecho, solo las respuestas 2xx irán a
onNext
.
Todo lo demás se envolverá en una
HttpException
y se enviará a
onError
.
Lo que también tiene sentido, porque sin el contenedor de
Response
, ¿qué
debería
emitirse a
onNext
?
Dado que la solicitud no tuvo éxito, lo único sensato para emitir sería
null
...