rxjava2 rxjava example android retrofit rx-java android-networking rx-android

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 ...