Okhttp Non IOException handling for Enqueue
See original GitHub issueAs I started to implement coroutines with Okhttp I migrated some calls from execute() to enqueue() to have cancellable Coroutines.
So far all is working well, with worker pool and everything, and then comes the non IO related exceptions that where not tested and are not handled by OkHttp at all when using enqueue.
The problem is that the crash occurs in Okhttp threads and so can’t be intercepted properly by the application.
Caused by android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)
at libcore.io.IoBridge.isConnected(IoBridge.java:267)
at libcore.io.IoBridge.connectErrno(IoBridge.java:187)
at libcore.io.IoBridge.connect(IoBridge.java:129)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:1)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:81)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:23)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:120)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:15)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:8)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:6)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:12)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:1)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:105)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:12)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:1)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:62)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:12)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:75)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:12)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:1)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:23)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:1)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:3)
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)
This user is probably rooted and have disabled internet permission by default, but application should be able to handle that. And there’s a few other errors that are common and Android and require handling.j
This was reported before https://github.com/square/okhttp/issues/3477 and the answer was we can’t handle that as it’s OS error, but I’m not sure the problem was correctly description in the issue naming and description and that after the user explained more in the issue it was not really analysed after. (There’s a second similar issue https://github.com/square/okhttp/issues/3465 that was close for the more or less same reason).
The fix proposed by the user to add an interceptor works, but when using generic reusable component this means that for each request I need to newbuilder.addinterceptor.build this is not efficient and that I lose the original exception for some exceptions I can parse the message and guess, but having the proper exception is better.
I’d like to request a way to properly handle those directly from OKhttp, I understand that it will be complex as interface default do not exist in Java for Android and that changing the callback exception type would not be binary compatible. But I hope there’s a way I did not thought about 😃 Errors happens on Android, application can handle them in synchronous ways by catching them and OkHttp should allow the app to get those and do something instead of crashing in place where the app can’t intercept.
Issue Analytics
- State:
- Created 5 years ago
- Comments:20 (19 by maintainers)
Top GitHub Comments
After discussion with Coroutine lead, probable cause is described at https://github.com/Kotlin/kotlinx.coroutines/issues/830 with some experimental workaround until proper way is made.
I have no idea why the stacktrace is fully the original and not wrapped in anything, but sounds like the only possible explanation.
I occur the same error. is’s coroutine’s problem. local scope async cannot catch error. https://stackoverflow.com/questions/50230466/kotlin-withcontext-vs-async-await
bad code:
to
correct code: