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

java.lang.IllegalStateException: closed #3336

Closed
siddhpuraamitr opened this issue Mar 18, 2020 · 2 comments
Closed

java.lang.IllegalStateException: closed #3336

siddhpuraamitr opened this issue Mar 18, 2020 · 2 comments

Comments

@siddhpuraamitr
Copy link

siddhpuraamitr commented Mar 18, 2020

I am using two kind of interceptor, one is HttpLoggingInterceptor and another one is my custom AuthorizationInterceptor

I am using below updated retrofit version library,

def retrofit_version = "2.7.2"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0'
implementation 'com.squareup.okhttp3:okhttp:4.4.0'

below is code

private fun makeOkHttpClient(): OkHttpClient {
        val logger = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
        return OkHttpClient.Builder()
            .addInterceptor(AuthorizationInterceptor(context)) <---- To put Authorization Barrier
            .addInterceptor(logger) <---- To log Http request and response
            .followRedirects(false)
            .connectTimeout(50, TimeUnit.SECONDS)
            .readTimeout(50, TimeUnit.SECONDS)
            .writeTimeout(50, TimeUnit.SECONDS)
            .build()
    }

When I try to execute below code, in file named SynchronizationManager.kt, it gives me an error.

var rulesResourcesServices = RetrofitInstance(context).buildService(RulesResourcesServices::class.java)
val response = rulesResourcesServices.getConfigFile(file).execute() <---In this line I am getting an exception... (which is at SynchronizationManager.kt:185)               

My RulesResourcesServices class is here

After debug I found that when below function called, at that time I am getting an exception

@GET("users/me/configfile")
    fun getConfigFile(@Query("type") type: String): Call<ResponseBody>

I am getting following error

java.lang.IllegalStateException: closed
at okio.RealBufferedSource.read(RealBufferedSource.kt:184)
at okio.ForwardingSource.read(ForwardingSource.kt:29)
at retrofit2.OkHttpCall$ExceptionCatchingResponseBody$1.read(OkHttpCall.java:288)
at okio.RealBufferedSource.readAll(RealBufferedSource.kt:293)
at retrofit2.Utils.buffer(Utils.java:316)<------- ANDROID IS HIGH-LIGHTING
at retrofit2.BuiltInConverters$BufferingResponseBodyConverter.convert(BuiltInConverters.java:103)
at retrofit2.BuiltInConverters$BufferingResponseBodyConverter.convert(BuiltInConverters.java:96)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute(DefaultCallAdapterFactory.java:97)
at android.onetap.SynchronizationManager.downloadFile(SynchronizationManager.kt:185)
at android.base.repository.LoginRepository.downloadConfigFilesAndLocalLogin(LoginRepository.kt:349)
at android.base.repository.LoginRepository.access$downloadConfigFilesAndLocalLogin(LoginRepository.kt:48)
at android.base.repository.LoginRepository$loginTask$2.onSRPLoginComplete(LoginRepository.kt:210)
at android.base.repository.LoginRepository$performSyncLogin$srpLogin$1$1.onSRPLogin(LoginRepository.kt:478)
at android.srp.SRPManager$SRPLoginOperation$execute$1.invokeSuspend(SRPManager.kt:323)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)

Below is screenshot, in that you can see that, I am getting output of file but don't know why it is throwing an exception.

enter image description here

checked Retrofit's Utils class

https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit2/Utils.java

static ResponseBody buffer(final ResponseBody body) throws IOException {
    Buffer buffer = new Buffer();
    body.source().readAll(buffer); <-This line throws an error.
    return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
  }

Update

Same thing is working fine with enqueue method.

response.enqueue(object : Callback<ResponseBody?> {

override fun onResponse(call: Call<ResponseBody?>, response: retrofit2.Response<ResponseBody?>) { 
 }
})
@JakeWharton
Copy link
Collaborator

Best guess is that you're reading and closing the response body in your interceptor which means it's not available to consume by the normal Retrofit internals. If you want to read the body in an interceptor and you don't plan on replacing it then it's best to use OkHttp's peekBody().

If it's not this, please isolate the behavior to a small executable sample or failing test so we can debug what's going on.

@siddhpuraamitr
Copy link
Author

siddhpuraamitr commented Mar 19, 2020

Hi @JakeWharton, issue is resolved. Thank you so much for your response, I have shared detail in StackOverflow, with your thanks, so it will be helpful for others.

farhan-arshad-dev added a commit to openedx-unsupported/edx-app-android that referenced this issue Feb 20, 2024
- replace `respose.toString()` with `response.peekBody(Long.MAX_VALUE).string()`
inspiration: square/retrofit#3336 (comment)

fixes: LEARNER-9831
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants