Okhttp: 3.14.1 interceptor regression

Created on 27 Apr 2019  Â·  12Comments  Â·  Source: square/okhttp

I think this is probably a bug in my client code, but it's a new behaviour so flagging anyway

https://github.com/yschimke/okurl/blob/5a40144ff173e055d60a67f0c51df1ccad07a419/src/main/kotlin/com/baulsupp/okurl/authenticator/RenewingInterceptor.kt#L34

Apr 27, 2019 9:25:20 AM com.baulsupp.cooee.ProdAppServices$client$1$1 log
INFO: [33 ms] requestHeadersStart
Apr 27, 2019 9:25:20 AM com.baulsupp.cooee.ProdAppServices$client$1$1 log
INFO: [33 ms] requestHeadersEnd
Apr 27, 2019 9:25:20 AM com.baulsupp.cooee.ProdAppServices$client$1$1 log
INFO: [34 ms] responseHeadersStart
Apr 27, 2019 9:25:20 AM com.baulsupp.cooee.ProdAppServices$client$1$1 log
INFO: [2835 ms] connectionReleased
Apr 27, 2019 9:25:20 AM com.baulsupp.cooee.ProdAppServices$client$1$1 log
INFO: [2836 ms] callEnd
Exception in thread "OkHttp Dispatcher" java.lang.IllegalStateException: cannot make a new request because the previous response is still open: please call response.close()
    at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:164)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at com.baulsupp.okurl.authenticator.RenewingInterceptor$intercept$1.invokeSuspend(RenewingInterceptor.kt:34)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:80)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at com.baulsupp.okurl.authenticator.RenewingInterceptor.intercept(RenewingInterceptor.kt:28)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:172)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
bug

Most helpful comment

@ysy950803 close the response before replacing it with the chain.proceed inside the while loop.

Thanks! It works!

while (!response.isSuccessful() && retryCount < RETRY_MAX_COUNT - 1) {
    retryCount++;
    response.close();
    response = chain.proceed(request);
}

All 12 comments

Closing under the assumption it's my bug

Yep, I think that might have previously been a leak.

Would you share what caused this? I just now encountered the same problem.

Encountered the same error in 3.14.0 and above, in lower versions everything working.

@alexv-anyvision this leak was previously silent; in OkHttp 3.14 we started to detect it and report on it.

Is there any workaround?

Is this the leak within an interceptor case? e.g. RenewingInterceptor in my case?

https://github.com/yschimke/okurl/commit/269bc114cee2529bba9cebdfceac7bce1b15a795#diff-c1ed79514e9258a543ba1c3eb1b45c3e

Yeah, interceptors must close the previous response before proceeding to the next.

So, this is still needed in the release 3.14.2 and 4.0.0, right ?

So how to ifx?
I have the same problem when adding a RetryInterceptor like this:

private static class RetryInterceptor implements Interceptor {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        int retryCount = 0;
        Request request = chain.request();
        okhttp3.Response response = chain.proceed(request);
        while (!response.isSuccessful() && retryCount < RETRY_MAX_COUNT - 1) {
            retryCount++;
            response = chain.proceed(request);
        }
        if (retryCount > 0) {
            Logger.w(TAG, "retryCount:" + retryCount);
        }
        return response;
    }
}

@ysy950803 close the response before replacing it with the chain.proceed inside the while loop.

@ysy950803 close the response before replacing it with the chain.proceed inside the while loop.

Thanks! It works!

while (!response.isSuccessful() && retryCount < RETRY_MAX_COUNT - 1) {
    retryCount++;
    response.close();
    response = chain.proceed(request);
}
Was this page helpful?
0 / 5 - 0 ratings