Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit 2 - Manage http "204 No content" and "200" with content for the same request

I'm using Retrofit 2 and OkHttp 3, with RxJava2

I'm doing a call to a server with some parameters. Base on the parameters, the server returns a JSON with a list of objects. But if there is nothing to return, instead of returning a JSON with an empty list, the server return '204 - No Content'. As a result I get a NullPointerException.

I know how to manage a JSON response, and I know how to manage a 204 response but not together for the same call.

I could use an interceptor, but as I have a lot of call, my Retrofit client is created once and then injected when necessary using Dagger2.

How can I manage this case?

like image 938
Eselfar Avatar asked Mar 08 '23 04:03

Eselfar


1 Answers

Based on @eurosecom suggestion I have solved my problem like described below. The only issue is I wanted the 'No Content' response, from the server, to be managed as a 'success' by Retrofit, but with this solution it's still managed as an error.

Retrofit client

return new OkHttpClient.Builder()
    .addInterceptor(new GeneralInterceptor(callback))
    .build


private static class GeneralInterceptor implements Interceptor {

    //... 

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder();
        Response response = chain.proceed(requestBuilder.build());

        // Throw specific Exception on HTTP 204 response code
        if (response.code() == 204) {
            throw new NoContentException("There is no content");
        }

        return response; // Carry on with the response
    }
}

In the Presenter

mModel.performRequest()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onErrorResumeNext(throwable -> {
        if (throwable instanceof NoContentException) {
            return Observable.empty();
        }

        return Observable.error(throwable);
    })
    .subscribe(res -> {
        //... Manage the result
    }, throwable -> {
        //... On error
    }
);
like image 149
Eselfar Avatar answered Apr 09 '23 14:04

Eselfar