1

I faced this issue when I tried to migrate my network calls from "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter" to builtin retrofit 2.6 suspend function.

Scenario, I am making multiple sequential network calls to fetch data from APIs. My first call succeeded without any problem but for the second retrofit call. It gives me the below error.

Changes that I made in my code,

  1. Removed the adapter library from app.gradle and update my retrofit to 2.7.
  2. Removed the await() call execution line and added "suspend" function in the retrofit interface method.
  3. Removed the Deferred variable retrofit interface method.

My Logcat console

2020-02-26 17:08:19.777 E: FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.chilindo, PID: 22114
    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$okhttp(Transmitter.kt:157)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at com.chilindo.base.network.ChilindoAPIL$Companion$invoke$$inlined$-addInterceptor$1.intercept(Interceptor.kt:144)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:194)
        at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

After retrofit 2.6

override suspend fun fetchUserProfile() {
        try {
            val result = chilindoAPI.fetchProfile()
            if (result.isSuccessful) {
                _userProfileTable.postValue(result.body())
            }
        } catch (e: HttpExceptionExtended) {
            e.printStackTrace()
        } catch (e: NoConnectivityException) {
            e.printStackTrace()
        }
    }

    override suspend fun fetchCategoriesResponse(domain: String, language: String) {
        try {
            val categoriesRequest = CategoriesRequest()
            categoriesRequest.countryName = domain
            categoriesRequest.language = language
            val result = chilindoAPI.fetchCategories(categoriesRequest)
            if (result.isSuccessful) {
                _categoriesResponse.postValue(result.body())
            }
        } catch (e: HttpExceptionExtended) {
            e.printStackTrace()
            _categoriesResponse.postValue(null)
        } catch (e: NoConnectivityException) {
            e.printStackTrace()
        }
    }

and API Interface

    @POST(ServiceTypes.USER_PROFILE)
    suspend fun fetchProfile(): Response<UserProfileTable>

    @POST(ServiceTypes.CATEGORIES)
    suspend fun fetchCategories(@Body categoriesRequest: CategoriesRequest): Response<List<CategoriesResponse>>
Attiq ur Rehman
  • 475
  • 1
  • 6
  • 21

1 Answers1

1

The bug is that your interceptor (com.chilindo.base.network.ChilindoAPIL) is not closing a response before issuing anither request. This was a silent leak on old OkHttp versions; today it's detected so you can avoid the leak.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128