Handling specific errors by sending another request transparently in retrofit
Asked Answered
R

1

6

Here's the case I'm trying to handle,

  • If a request is executed, and the response indicates the auth token is expired,
  • send a refresh token request
  • if the refresh token request succeeds, retry the original request

This should be transparent to the calling Activity, Fragment... etc. From the caller's point of view, it's one request, and one response.

I've achieved this flow before when using OkHttpClient directly, but I don't know how to achieve this in Retrofit.

Maybe something related to this open issue about a ResponseInterceptor?

If there's no straight-forward way to achieve this in retrofit, what would be the best way to implement it? A base listener class?

I'm using RoboSpice with Retrofit as well, if it can be helpful in such case.

Ravishing answered 25/2, 2014 at 12:58 Comment(3)
Did you ever find a solution you liked for this? I have a similar use case... it looks like retrofit 2.0 is going to be able to handle this in a straightforward way, but my googling hasn't revealed anything for the 1.X versionsMinstrel
There's another open question for the same case here: #22450536 Check the comments on the question, there might be some leads. Since I'm using RoboSpice, I think this would belong to a base RetrofitSpiceRequest inside loadFromNetwork(). I didn't have the time to get back to it though, but I will try it soon.Ravishing
@Minstrel If you are using OkHttp as your HTTP client and Retrofit >= 1.9 then you can use the new Interceptor. See my answer here for an example. Otherwise, we will need to wait for Retrofit 2.0 to be released.Lyricist
R
2

Since I'm using RoboSpice, I ended up doing this by creating an abstract BaseRequestListener.

public abstract class BaseRequestListener<T> implements RequestListener<T> {

    @Override
    public void onRequestFailure(SpiceException spiceException) {
        if (spiceException.getCause() instanceof RetrofitError) {
            RetrofitError error = (RetrofitError) spiceException.getCause();
            if (!error.isNetworkError() 
                && (error.getResponse().getStatus() == INVALID_ACCESS_TOKEN_STATUS_CODE)) {
                //I'm using EventBus to broadcast this event,
                //this eliminates need for a Context
                EventBus.getDefault().post(new Events.OnTokenExpiredEvent());
                //You may wish to forward this error to your listeners as well,
                //but I don't need that, so I'm returning here.
                return;
                }
         }
         onRequestError(spiceException);
    }

    public abstract void onRequestError(SpiceException spiceException);
}
Ravishing answered 8/4, 2014 at 10:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.