It seems that an issue with the underlying buffer / connection may lead to an Exception (or even Error!) thrown from close method of the response. An example:
java.lang.AssertionError: java.io.EOFException
at okio.Buffer.clear(Buffer.java:932)
at okio.RealBufferedSource.close(RealBufferedSource.java:477)
at okhttp3.internal.Util.closeQuietly(Util.java:139)
What surprised us is Util.closeQuietly in the stacktrace.
Isn't it supposed to catch such errors and e.g. log instead of re-throwing?
Yes, probably two questions to answer
1) Should closeQuietly throw RuntimeException or AssertionErrors?
2) Should okio ever turn a user input or end of stream into a non IOException?
This particular crash is caused by unsafe concurrent access to a Buffer. Perhaps one code path is calling close() while another code path is attempting to read? Okio streams are not safe for concurrent use, and calling close() while another thread is reading or writing is unsupported.
The word _quietly_ in this context is intended to hide IOExceptions only. The AssertionError here is an invariant being violated, and I don't think it makes sense to attempt to recover from unexpected crashes.
Perhaps one code path is calling close() while another code path is attempting to read? Okio streams are not safe for concurrent use, and calling close() while another thread is reading or writing is unsupported.
Oh wow, TIL! It may be problematic because we return InputStream to the user but close on our end on certain conditions. Could you please advice how to prevent errors here?
The word quietly in this context is intended to hide IOExceptions only. The AssertionError here is an invariant being violated, and I don't think it makes sense to attempt to recover from unexpected crashes.
FTR we've seen other exceptions (like AIOOBE from the tweet), and the expectation was that closeQuietly would suppress _any_ error (except the ones caused by JVM's misbehaviour like OOM or similar)
If it had that behavior it would hide bugs, so perhaps we should change its name to more clearly indicate that we're ignoring only IOException and its subtypes.
I think you want cancel(), not close:
Too bad about confusion with closeQuietly(). It's not public API so I assume if you鈥檙e reading the code you鈥檙e also seeing the implementation.
Should we flag this type of problem in debug modes? E.g. check for concurrent calls?
We could do some basic stuff, like what ArrayList does with its modCount. But there鈥榮 a potential performance cost, especially if we used volatile to tell colliding threads about each other.
OK, so multiple works arounds or fixes
As far as fixes go
We want this error otherwise we hide real problems, hence the method is doing the right thing.
No fix possible within the scope of OkHttp, so closing this out. Thanks for the report @bsideup
Most helpful comment
Yes, probably two questions to answer
1) Should closeQuietly throw RuntimeException or AssertionErrors?
2) Should okio ever turn a user input or end of stream into a non IOException?
https://twitter.com/bsideup/status/1273169998018752512