Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get response status code using Retrofit 2.0 and RxJava

People also ask

How do I check my retrofit response code?

You can catch the response before retrofits Callback and get status code from the response: OkHttpClient client = new OkHttpClient(); client. interceptors(). add(new Interceptor(){ @Override public Response intercept(Chain chain) throws IOException{ Request request = chain.

What is the difference between RxJava and retrofit?

Rx gives you a very granular control over which threads will be used to perform work in various points within a stream. To point the contrast here already, basic call approach used in Retrofit is only scheduling work on its worker threads and forwarding the result back into the calling thread.


Instead of declaring the API call like you did:

Observable<MyResponseObject> apiCall(@Body body);

You can also declare it like this:

Observable<Response<MyResponseObject>> apiCall(@Body body);

You will then have a Subscriber like the following:

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!
    }
}

So, server responses with an error code will also be delivered to onNext and you can get the code by calling reponse.code().

http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html

EDIT: OK, I finally got around to looking into what e-nouri said in their comment, namely that only 2xx codes will to to onNext. Turns out we are both right:

If the call is declared like this:

Observable<Response<MyResponseObject>> apiCall(@Body body);

or even this

Observable<Response<ResponseBody>> apiCall(@Body body);

all responses will end up in onNext, regardless of their error code. This is possible because everything is wrapped in a Response object by Retrofit.

If, on the other hand, the call is declared like this:

Observable<MyResponseObject> apiCall(@Body body);

or this

Observable<ResponseBody> apiCall(@Body body);

indeed only the 2xx responses will go to onNext. Everything else will be wrapped in an HttpException and sent to onError. Which also makes sense, because without the Response wrapper, what should be emitted to onNext? Given that the request was not successful the only sensible thing to emit would be null...


Inside onError method put this to get the code

((HttpException) e).code()

You should note that as of Retrofit2 all responses with code 2xx will be called from onNext() callback and the rest of HTTP codes like 4xx, 5xx will be called on the onError() callback, using Kotlin I've came up with something like this in the 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))
  }