Eselfar
Eselfar

Reputation: 3869

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?

Upvotes: 5

Views: 7142

Answers (2)

Eselfar
Eselfar

Reputation: 3869

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
    }
);

Upvotes: 7

eurosecom
eurosecom

Reputation: 2992

I use onErrorResumeNext for error response. For example

mSubscription.add(mViewModel.getMyPohybyFromSqlServer("3", drupoh)
            .subscribeOn(Schedulers.computation())
            .observeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
            .doOnError(throwable -> { Log.e(TAG, "Error xxx " + throwable.getMessage());
                hideProgressBar();
                Toast.makeText(getActivity(), "Server not connected", Toast.LENGTH_SHORT).show();
            })
            .onErrorResumeNext(throwable -> empty())
            .subscribe(this::setPohyby));

Upvotes: 1

Related Questions