Skip to content
This repository has been archived by the owner on May 1, 2023. It is now read-only.

OkHttp3 Interceptor crash #346

Closed
juandiana opened this issue Jan 27, 2016 · 27 comments
Closed

OkHttp3 Interceptor crash #346

juandiana opened this issue Jan 27, 2016 · 27 comments

Comments

@juandiana
Copy link

I just upgraded OkHttp to version 3.0.1 and Stetho to version 1.3.0 (and its corresponding new OkHttp3 network interceptor).

I'm experiencing the following NullPointerException when inspecting HTTP traffic:

E/stetho: com.facebook.stetho.inspector.elements.android.DialogFragmentDescriptor.getChildren() emitted a null child at position 0 for element LayoutFragment{3a8b2dd3 #0 id=0x7f0c00dc}
E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
         Process: com.artech.androidbasictest.testgxsalto, PID: 29855
         java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
         at com.facebook.stetho.okhttp3.StethoInterceptor$OkHttpInspectorResponse.connectionId(StethoInterceptor.java:229)
         at com.facebook.stetho.inspector.network.NetworkEventReporterImpl.responseHeadersReceived(NetworkEventReporterImpl.java:143)
         at com.facebook.stetho.okhttp3.StethoInterceptor.intercept(StethoInterceptor.java:73)
         at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:681)
         at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
         at okhttp3.RealCall.getResponse(RealCall.java:241)
         at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
         at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
         at okhttp3.RealCall.access$100(RealCall.java:30)
         at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
         at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:33)
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
         at java.lang.Thread.run(Thread.java:818)
@jasta
Copy link
Contributor

jasta commented Jan 27, 2016

This looks like the same issue as with okhttp2, you may have accidentally used a regular interceptor instead of a network interceptor. I keep forgetting to actually fix this with a proper error message :(

@juandiana
Copy link
Author

I did notice that there are two methods for adding an interceptor when building an OkHttpClient instance. Notice that I actually used the addNetworkInterceptor method, as follows:

mHttpClient = new OkHttpClient.Builder()
        .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        .addNetworkInterceptor(new StethoInterceptor())
        .build();

@jasta
Copy link
Contributor

jasta commented Jan 27, 2016

Hmm, then I'm puzzled. @swankjesse?

@swankjesse
Copy link
Contributor

The interceptor might be returning a null connection after that physical connection has been released back to the pool. Perhaps the response has a Connection: close header and the response body is empty? Regardless the fix is pretty easy. I should fix OkHttp to keep a reference to the connection while the interceptor is run so this doesn’t happen.

@kypeli
Copy link

kypeli commented Mar 8, 2016

I am facing the same crash here.

    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.facebook.stetho:stetho:1.3.1'
    compile 'com.facebook.stetho:stetho-okhttp3:1.3.1'

Please note that since OkHttp3, you can't add the interceptor with client.networkInterceptors().add(new StethoInterceptor()) because OkHttp3 is immutable. So you have to use the Builder approach.

Could the crash be related to this?

My device is connected since I can use Vysor and debug the app through the same connection, so it's not a connection issue.

@jasta
Copy link
Contributor

jasta commented Mar 8, 2016

@kypeli your crash is unrelated.

@kypeli
Copy link

kypeli commented Mar 8, 2016

@jasta Thanks for the clarification. I see the same stack trace or null pointer exception, so must be the same issue as described in this ticket. Hopefully fixed soon :)

@dave-r12
Copy link

Hello, we've merged in a change that should resolve this that will be going out with OkHttp 3.3.

@baurine
Copy link

baurine commented Mar 26, 2016

I also face the same crash:

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
    at com.facebook.stetho.okhttp3.StethoInterceptor$OkHttpInspectorResponse.connectionId(StethoInterceptor.java:229)
    at com.facebook.stetho.inspector.network.NetworkEventReporterImpl.responseHeadersReceived(NetworkEventReporterImpl.java:143)
    at com.facebook.stetho.okhttp3.StethoInterceptor.intercept(StethoInterceptor.java:73)
    at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:681)
    at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
    at okhttp3.RealCall.getResponse(RealCall.java:241)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
    at cn.pyromusic.pyro.api.RestClient$1.intercept(RestClient.java:69)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
    at okhttp3.RealCall.access$100(RealCall.java:30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)

It happens when a http request returns 204 and has no response body.

I debuged, as above said, it was caused by null connection().

I use stetho 1.3.1 and retrofit 2.0 (it depends okhttp 3.2.0)

@jasta
Copy link
Contributor

jasta commented Apr 13, 2016

@baurine can you test with okhttp 3.3 to verify that the upstream fix works? I don't think this is necessarily a Stetho issue.

@forzajuve
Copy link

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at com.facebook.stetho.okhttp3.StethoInterceptor$OkHttpInspectorResponse.connectionId(StethoInterceptor.java:229)
at com.facebook.stetho.inspector.network.NetworkEventReporterImpl.responseHeadersReceived(NetworkEventReporterImpl.java:143)
at com.facebook.stetho.okhttp3.StethoInterceptor.intercept(StethoInterceptor.java:73)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:681)
at com.youku.laifeng.libcuteroom.http.LFHttpClient$LFInterceptor.intercept(LFHttpClient.java:1311)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:681)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
at okhttp3.RealCall.getResponse(RealCall.java:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)

compile 'com.facebook.stetho:stetho:1.3.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.3.1'

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS);
builder.writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS);
builder.readTimeout(READ_TIME_OUT, TimeUnit.SECONDS);
builder.networkInterceptors().add(new StethoInterceptor());
mOkHttpClient = builder.build();

@Baleizao
Copy link

@jasta I have the same problem and did some digging. The source of the crash is that okhttp3.RealCall.connection() always returns null. This is its current source code in master:

public Connection connection() {
  return null;
}

The fix that @swankjesse made for #2288 fixes the crash that @baurine saw but doesn't fix the case of okhttp3.RealCall being used.

I also noticed that we only need the connection object to compute a hash code that will become the connection ID, so maybe we don't even need a reference to the connection in the first place. Is there a chance we can replace it by something else (e.g. a counter or some random number)?

@swankjesse
Copy link
Contributor

Yikes. I’ll fix this one too.

@swankjesse
Copy link
Contributor

(Or more specifically, I’ll ask @dave-r12 to fix it!)

@dave-r12
Copy link

@Baleizao I do not see that RealCall has a connection() method. I think you might be referring to the ApplicationInterceptorChain class? That class handles Application interceptors, which are different than network interceptors (see https://github.com/square/okhttp/wiki/Interceptors). Stetho is using a network interceptor, so that class should not matter.

@Baleizao
Copy link

Gah... you're absolutely right! I accidentally installed the StethoInterceptor as an application interceptor instead of as a network interceptor, hence the crash. Sorry folks! All sorted now.

@baiiu
Copy link

baiiu commented May 17, 2016

Yes, it is. it is worked by using addNetworkInterceptor method.

@baurine
Copy link

baurine commented May 22, 2016

@jasta so so sorry, I just remember the thing you asked me to do. but I can't find okhttp 3.3, the latest version is still 3.2.0. I tried compile 'com.squareup.okhttp3:okhttp:3.3.0-SNAPSHOT', but gradle tell me Failed to resolve: com.squareup.okhttp3:okhttp:3.3.0-SNAPSHOT. I read the above comments, it seems this bug has already fixed, right?

@baurine can you test with okhttp 3.3 to verify that the upstream fix works? I don't think this is necessarily a Stetho issue.

One more thing, I updated the android studio from 1.5 to 2.1 stable, debug my project again, and this bug didn't reproduce, I tried many times. It is a little strange.

@juandiana
Copy link
Author

@baurine According to OkHttp's README:

Snapshots of the development version are available in Sonatype's snapshots repository.

So, you just need to add the repository url to your gradle script repositories section.

repositories {
    ...
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
}

@baurine
Copy link

baurine commented May 23, 2016

@juandiana thank you! it works. Now I used the okhttp 3.3, test again, the crash has not happened again. but my develop environment is not as same as before, I updated the android studio from 1.5 to 2.1. any way, if I meet this bug again, I will report.

@jasta
Copy link
Contributor

jasta commented Jun 2, 2016

Can this issue be closed out? It looks like the thread has settled a bit and okhttp 3.3 is indeed confirmed to fix, yes?

@fzymek
Copy link

fzymek commented Nov 30, 2016

I was using okhttp as transitive dependency from retrofit2 and this crash happened to me as well. After including direct dependency to okhttp:3.4.2 it is no longer happening.

@cristan
Copy link

cristan commented Oct 11, 2017

A null check has been committed on master, but no release has been made after 1.5.0 yet.

@ghost
Copy link

ghost commented Nov 6, 2017

When are we expecting the null check on master to be updated into a 1.5.1 release? We're blocked using stetho's network feature because of the crash fixed with @cristan's commit.

@naturalwarren
Copy link

Is your interceptor registered as a network interceptor? #549 provides a better error message when you're incorrectly registered as a vanilla interceptor.

@jasta
Copy link
Contributor

jasta commented Jan 2, 2018

We don't actually want folks using StethoInterceptor as an app interceptor (instead of a network interceptor), so we've gone further and are now just throiwng a clear error message to this effect. See #584.

@jasta jasta closed this as completed Jan 2, 2018
@anjinlu
Copy link

anjinlu commented Jul 24, 2018

App Crashes when the request is cancelled and the interceptor return NULL.

In my code, "Cancelled" exception was caught, return NULL or re-throw the exception cause the app crash.

public class HttpInterceptor : Java.Lang.Object, IInterceptor {
	public Response Intercept(IInterceptorChain chain) {
		Response response = null;
		try {
			Request request = chain.Request();
			response = chain.Proceed(request);
		} catch (Exception e) {
		}
		return response;
	}
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests