3

I get java.io.InterruptedIOException: timeout rarely in my office.

However, it keeps occurring in stores.

So, I set

client.addInterceptor(httpLoggingInterceptor)
            .connectTimeout(5, TimeUnit.SECONDS)
            .callTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)

But, this didn't work.

So, What I did in .enqueue()

fun startPay(){
    // ... Service Generator and so on...
    override fun onFailure(call: Call<ResultData>, t: Throwable) {
        when(t){
            is InterruptedIOException ->{
                Thread.sleep(1000)
                startPay()
            }
            else->{
                Toast.makeText(this, t.toString(), Toast.LENGTH_SHORT).show()
            }
        }
    }
}

I am guessing this occurs because more than two clicks in short time or I am calling 3 consecutively after 200 response. ex. A call -> 200 response -> B call -> 200 response -> C call -> 200 response -> UI Update. Now, it catches the exception and retry the api call. I think this has no reason to be interrupted by the same thread or other thread..

This solution is fine in general. But the problem is when I pay something It must call just once.

this InterrupedIOException: timeout(Not SocketTimeout) seems cancel the connection before getting the response from server, the server is sending the response well and has no problem.

Some questions in stackoverflow mentioned Crashlystics. I am using it but I shouldn't remove it.

I am using:

    // Firebase
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:26.0.0')
    implementation 'com.google.firebase:firebase-core'
    implementation 'com.google.firebase:firebase-auth'
    implementation 'com.google.firebase:firebase-auth-ktx'
    implementation 'com.google.firebase:firebase-config' // remote config
    implementation 'com.google.firebase:firebase-analytics'
    implementation 'com.google.firebase:firebase-analytics-ktx'
    implementation 'com.google.firebase:firebase-crashlytics'
    implementation 'com.google.firebase:firebase-perf'
    implementation 'com.google.firebase:firebase-config-ktx'

    // Network
    // okhttp: https://github.com/square/okhttp
    implementation 'com.squareup.okhttp3:okhttp:4.7.2'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
    implementation 'org.conscrypt:conscrypt-android:2.2.1' // optional

The error is here:

java.io.InterruptedIOException: timeout
W/System.err: java.io.InterruptedIOException: timeout
W/System.err:     at okhttp3.internal.connection.RealCall.timeoutExit(RealCall.kt:384)
W/System.err:     at okhttp3.internal.connection.RealCall.maybeReleaseConnection(RealCall.kt:346)
W/System.err:     at okhttp3.internal.connection.RealCall.noMoreExchanges$okhttp(RealCall.kt:310)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:205)
W/System.err:     at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:502)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
W/System.err:     at java.lang.Thread.run(Thread.java:761)
W/System.err: Caused by: java.io.IOException: Canceled
W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:72)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at com.example.helper.api.ServiceGenerator$createService$$inlined$-addInterceptor$1.intercept(Interceptor.kt:87)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
W/System.err:   ... 4 more
c-an
  • 3,543
  • 5
  • 35
  • 82

1 Answers1

1

One of the possible reasons is a bug in okhttp3. When you settled timeouts, POST requests can become canceled under IPv6 networks with a log like described. I am able to reproduce it using IPv6Droid application for tests (it is not free).

To fix it just remove .callTimeout().

BArtWell
  • 4,176
  • 10
  • 63
  • 106
  • Can you explain it more? And how can I reproduce it? – c-an Nov 11 '21 at 17:29
  • I don't know a reason of this issue. You can reproduce it with the next steps: 1. Set all of timeouts for OkHttpClient.Builder including callTimeout to some value, e.g. 30 seconds. 2. Implement code that sends POST-request (it was a simple POST request with JSON inside in my case). 3. Install IPv6Droid, setup and launch it. It will establish IPv6 VPN connection. 4. Launch your test application on the same device. You will get an error InterruptedIOException timeout. Then remove callTimeout() method and problem will gone. – BArtWell Nov 12 '21 at 12:26