I'm using a android-priority-jobqueue and I use retrofit to make synchronous calls to my rest api but i'm unsure how to handle errors like 401 Unauthorized errors which I send back json stating the error. Simple when doing async calls but I'm adapting my app for job manager. below is a simple try catch for IO exceptions, but 401's 422's etc? How to do this?
try {
PostService postService = ServiceGenerator.createService(PostService.class);
final Call<Post> call = postService.addPost(post);
Post newPost = call.execute().body();
// omitted code here
} catch (IOException e) {
// handle error
}
EDIT
The use of the retrofit response object was the clincher for me, returning the retrofit response object allowed me to
Response<Post> response = call.execute();
if (response.isSuccessful()) {
// request successful (status code 200, 201)
Post result = response.body();
// publish the post added event
EventBus.getDefault().post(new PostAddedEvent(result));
} else {
// request not successful (like 400,401,403 etc and 5xx)
renderApiError(response);
}
Check response code and show the appropriate message.
Try this:
PostService postService = ServiceGenerator.createService(PostService.class);
final Call<Post> call = postService.addPost(post);
Response<Post> newPostResponse = call.execute();
// Here call newPostResponse.code() to get response code
int statusCode = newPostResponse.code();
if(statusCode == 200)
Post newPost = newPostResponse.body();
else if(statusCode == 401)
// Do some thing...
Putting checks for 401 on every response is not a very good approach. Instead one can apply this check at the base level i.e. while creating an object for Retrofit, through the interceptors. Have a look:
public synchronized static Retrofit getClientWithRetry(final Context ctx) {
if (clientWithRetry == null) {
Interceptor responseCodeInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == 401) {
Log.d(LOG_TAG, "Intercepted Req: " + response.toString());
Response r = retryWithFreshToken(request, chain);
return r;
}
return response;
}
};
int cacheSize = 10 * 1024 * 1024; // 10 MB
Cache cache = new Cache(ctx.getCacheDir(), cacheSize);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.addInterceptor(responseCodeInterceptor)
.cache(cache)
.build();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client);
clientWithRetry = builder.build();
}
return clientWithRetry;
}
Here internally if a 401 is observed a new chained request can be made and token can be fetched. Post which the original request can be completed. Taken from this Retrofit retry tutorial.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With