Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException in okhttp3.internal.http.RealInterceptorChain.proceed with synchronous implementation. Thousands of reports #3676

Closed
rfoa opened this issue Nov 6, 2017 · 7 comments
Labels
needs info More information needed from reporter

Comments

@rfoa
Copy link

rfoa commented Nov 6, 2017

I use Retrofit2 in my project and lately I'm getting thousands of daily errors from okHttp, according to the Google Play Console Crashes Reports.
Although not directly handle the okHttp, the error log only refer to it... If necessary, I post in the Retrofit2 Github too.

The errors started happening after I started using the Refrofit synchronously (call.execute) from within AsyncTaskLoader.
I think my implementation is right, since I call call.execute() from within the loadInBackground() method and make the appropriate try/catch.
However, when using Retrofit asynchronously (call.enqueue) there was no error.

I thought Retrofit was returning a null object after it was created (APIServiceGenerator.createService), but the problem continues even though the code is surrounded by a NullPointerException try/catch.

Unfortunately I can not debug this error because the same error does not occur in my development environment, even testing on real devices and forcing connection failures. Errors only happen when the app is in production.

  • Is this a bug? Is there a workaround?
  • Is there anything wrong with my Retrofit synchronous implementation?
  • Is there any incompatibility of Retrofit2/okHttp with AsyncTaskLoader?
  • I use custom Interceptor, can it be related?

Please help me. Thanks.
Note: at the moment I can not use RxJava, so I used the AsyncTaskLoader.

List of OS Version

  • Android 7.0 -14.029 reports (82,5%)
  • Android 7.1 - 2.885 reports (17,0%)
  • Android 6.0 - 67 reports (0,4%)
  • Android 4.4 - 8 reports (0,01%)

List of Devices

  • Moto G Plus (5th Gen) (potter_nt) - 3.348 reports (9,7%)
  • Moto G (5th Gen) (cedric) - 2.893 reports (17,0%)
  • Moto G(4) Plus (athene_f) - 2.762 reports (16,2%)
  • Moto Z Play Droid (addison) - 1.068 reports (6,3%)
  • Moto G(4) (athene_t) - 914 reports (5,4%)
  • LG K10 (2017) (mlv5) - 665 reports (3,9%)
  • Galaxy A5(2017) (a5y17lte) - 272 reports (1,6%)
  • LG K10 Power (mlv7) - 231 reports (1,4%)

Google Play Error Report 1

java.lang.NullPointerException:
  at okhttp3.internal.http.RealInterceptorChain.request(RealInterceptorChain.java)
  at <OR> okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java)
  at okhttp3.internal.http.RealInterceptorChain.request (RealInterceptorChain.java)
  or                     .proceed (RealInterceptorChain.java)
  at okhttp3.RealCall.getResponseWithInterceptorChain (RealCall.java)
  at okhttp3.RealCall$AsyncCall.execute (RealCall.java)
  at okhttp3.internal.NamedRunnable.run (NamedRunnable.java)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
  at java.lang.Thread.run (Thread.java:776)

Google Play Error Report 2

java.lang.NullPointerException:
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
	at java.lang.Thread.run(Thread.java:761)

Project dependencies

    compile 'com.google.code.gson:gson:2.8.2'
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'

My simple AsyncTaskLoader

 static class ItemLoader extends AsyncTaskLoader<Item> {

        private int itemID;
        private Item item;
        private APIError error;

        public ItemLoader(Context context, int itemID) {
            super(context);
            this.itemID = itemID;
        }

        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            if(item != null) {
                deliverResult(item);
            }

            // Something has changed or we have no data, so kick off loading it
            if(takeContentChanged() || item == null) {
                forceLoad();
            }
        }

        @Override
        public Item loadInBackground() {
            if(itemID > Item.NO_ID) {
                try {
                    final ItemService service = APIServiceGenerator.createService(ItemService.class);
                    final Call<Item> call = service.getItem(itemID);

                    try {
                        Response<Item> response = call.execute();
                        if(response.isSuccessful()) {
                            final Item item = response.body();
                            if(item != null){
                                return item;
                            }

                        } else {
                            error = ErrorUtils.parseError(response, getContext());
                        }

                    } catch (IOException e) {
                        LogHelper.e(TAG, e, " - IOException in ItemLoader.loadInBackground()");

                    } catch (RuntimeException e) {
                        LogHelper.e(TAG, e, " - RuntimeException in ItemLoader.loadInBackground()");
                    }

                } catch (NullPointerException e) {
                    LogHelper.e(TAG, e, " - NullPointerException in ItemLoader.loadInBackground()");
                }

            }

            return null;
        }

        @Override
        public void deliverResult(Item data) {
            if(data != null) {
                error = null;
            }

            item = data;
            super.deliverResult(data);
        }
    }
@JakeWharton
Copy link
Member

What version of OkHttp are you using? Have you tried 3.9.0?

@rfoa
Copy link
Author

rfoa commented Nov 6, 2017

I don't know... I use the version embedded in Retrofit2 v2.3.0.
How can I force the retrofit to use version 3.9.0 of OkHttp?

@JakeWharton
Copy link
Member

JakeWharton commented Nov 6, 2017 via email

@rfoa
Copy link
Author

rfoa commented Nov 6, 2017

Ok, I got it. I'll do it. Thanks.
As soon as I have something new I'll post it here.

Do you have any idea of the cause of this error?

@rfoa rfoa closed this as completed Nov 6, 2017
@rfoa rfoa reopened this Nov 6, 2017
@yschimke yschimke added the needs info More information needed from reporter label Nov 19, 2017
@yschimke
Copy link
Collaborator

@rfoa any luck reproducing with 3.9.0 or 3.9.1? If not, I'll close and you can reopen once we can reproduce on a recent version.

@rfoa
Copy link
Author

rfoa commented Nov 21, 2017

I've released an update from my application to production using a staged rollout, so I can not say with 100% accuracy.
But using version 3.9.0 seems not to have solved.

@rfoa
Copy link
Author

rfoa commented Nov 21, 2017

I analyzed the error reports carefully and can say that the problem has been solved.
In this update I made two changes:

  • I forced the use of version 3.9.0 as explained above.
  • I changed the code, doing Retrofit to work asynchronously (call.enqueue) from within a simple Loader... I no longer use AsyncTaskLoader.

But I can not say which change corrected the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs info More information needed from reporter
Projects
None yet
Development

No branches or pull requests

3 participants