With a new version of okhttp(4.9.0, not sure if it was in lower versions) and Retrofit 2.9.0(also lower versions). I started to see in firebase and google analytics reports about UnknownHostException. I tried to repro this crash and found that it is happening when the internet is off or very low quality. I call addInterceptor in the framework layer and see that it’s crashing in intercept fun. I don’t wanna see this crash in my crash analytics.
Is it any way to handle it in “override fun intercept” (I can catch this error there before it goes to Real funs)?
Here is one of the log from Firebase:
at libcore.io.Linux.android_getaddrinfo(Linux.java) at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74) at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200) at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74) at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135) at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103) at java.net.InetAddress.getAllByName(InetAddress.java:1152) at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:49) at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:164) at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:129) at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:205) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74) at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at com.slipstream.accuradio.framework.intercertors.ApiInterceptor.intercept(ApiInterceptor.kt:23) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517) 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:919).
Thank you
Advertisement
Answer
You should really be catching and handling this exception outside the interceptor in your normal application code. For a correct solution you could also look at whether a cache and serving stale results would help.
But within an interceptor you really only have three choices,
- throw an IOException, or
- in the case of an application Interceptor (not network interceptors) you can redirect it somehow. This only helps if you have an alternate server, on a working network, so this probably doesn’t help.
- Return a fake response you build yourself, but this seems strange instead of just dealing with the io exception in your calling code.