android
android copied to clipboard
Fix crash on widget update when internet is not connected
Summary
This is the best of what I could come with to solve my issue of this app crashing. It happens when I have WiFi and mobile date turned off and I turn on the screen. I also came into a conclusion that the culprit is my temperature widget, though it's nothing out of ordinary. The error I got:
java.net.UnknownHostException: Unable to resolve host "<my domain>": No address associated with hostname at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124) ... and so on
I think it would be better to check for internet access before even doing the request but that's beyond my java skills.
Screenshots
Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#
Any other notes
I'm not able to reproduce the crash, could you share the full stacktrace for the issue you experienced?
Process: io.homeassistant.companion.android.debug PID: 20146 UID: 10327 Flags: 0x30e8bf46 Package: io.homeassistant.companion.android.debug v1 (LOCAL-full) Foreground: No Process-Runtime: 218810783 Build: asus/EU_I006D/ASUS_I006D:12/SKQ1.210821.001/31.1010.0410.72:user/release-keys Loading-Progress: 1.0
java.net.UnknownHostException: Unable to resolve host "<my domain>": No address associated with hostname at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124) 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 okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:221) 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:920) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@67d14a2, Dispatchers.Main]
I'm certain there something more required to reproduce this. It does not occur on a clean installation right away. I have also experimented with replacing domain with server IP (via hosts) and the error was different then:
Process: io.homeassistant.companion.android PID: 6793 UID: 10262 Flags: 0x20c8be44 Package: io.homeassistant.companion.android v2398 (2022.6.0-full) Foreground: Yes Process-Runtime: 163081602 Build: asus/EU_I006D/ASUS_I006D:12/SKQ1.210821.001/31.1010.0410.72:user/release-keys Loading-Progress: 1.0
java.net.ConnectException: Failed to connect to <my domain>/<my ip>:443 at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:297) at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:207) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226) 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 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:920) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@2e64409, Dispatchers.Main] Caused by: java.net.ConnectException: failed to connect to <my domain>/<my ip> (port 443) from /:: (port 0) after 10000ms: connect failed: ENETUNREACH (Network is unreachable) at libcore.io.IoBridge.connect(IoBridge.java:188) at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142) 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.Platform.connectSocket(Platform.kt:128) at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295) ... 18 more Caused by: android.system.ErrnoException: connect failed: ENETUNREACH (Network is unreachable) at libcore.io.Linux.connect(Native Method) at libcore.io.ForwardingOs.connect(ForwardingOs.java:204) at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:157) at libcore.io.ForwardingOs.connect(ForwardingOs.java:204) at libcore.io.IoBridge.connectErrno(IoBridge.java:219) at libcore.io.IoBridge.connect(IoBridge.java:180) ... 26 more
I'm now able to get the second stacktrace but it is thrown in onFailure for me (so it doesn't crash the app) 🤔
The proposed solution ~would work though and~ is consistent with other error handling for the websocket.
Because this is dealing with suspend functions simply throwing a try catch around it won't actually catch the exception. To do it properly you need to pass an exception handler into the launch function to correctly catch the issue.