Reputation: 969
I have built a codename one android app that connects a restdb.io database backend using REST. However, I am having random network failures like below
> [EDT] 0:4:26,949 - Exception: java.net.ConnectException - Failed to connect to ziemozi-a3ef.restdb.io/188.166.28.84:443
> java.net.ConnectException: Failed to connect to
> ziemozi-a3ef.restdb.io/188.166.28.84:443 at
> com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:147)
> at
> com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
> at
> com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
> at
> com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
> at
> com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
> at
> com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:302)
> at
> com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:245)
> at
> com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
> at
> com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
> at
> com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
> at
> com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
> at
> com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
> at
> com.codename1.impl.android.AndroidImplementation.getResponseCode(AndroidImplementation.java:6113)
> at
> com.codename1.io.ConnectionRequest.performOperationComplete(ConnectionRequest.java:905)
> at
> com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:341)
> at
> com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60)
> at java.lang.Thread.run(Thread.java:919)
OR
> java.net.SocketTimeoutException: timeout
at com.android.okhttp.okio.Okio$3.newTimeoutException(Okio.java:214)
at com.android.okhttp.okio.AsyncTimeout.exit(AsyncTimeout.java:263)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:217)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:770)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:642)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
at com.codename1.impl.android.AndroidImplementation.getResponseCode(AndroidImplementation.java:6113)
at com.codename1.io.ConnectionRequest.performOperationComplete(ConnectionRequest.java:905)
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:341)
at com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.net.SocketException: socket is closed
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:554)
at com.android.okhttp.okio.Okio$2.read(Okio.java:138)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
This happens in both simulator and device. And also when using fixed internet or mobile internet though it appears to happen more with mobile internet,
Upvotes: 2
Views: 86
Reputation: 6249
Both of the logs you reported seem to refer to connectivity issues, rather than server-side errors. You can't avoid connectivity issues, in fact, you should assume them to be normal, especially on mobile devices. The question then is how to handle them.
There is no universally valid answer, it depends on what you want to achieve. What many apps do, in these cases, is to report the problem to the user while continuously trying to repeat the failed operation, i.e. in this case the REST request, until an HTTP code is received in response.
For this kind of approach, I had asked a question back in the day, you can read it here: Distinguish between server-side errors and connection problems
In short, I removed the default error handling code from init() and I invoke the following well tested and working method for the purpose (it is a version based on the code in Distinguish between server-side errors and connection problems), that you can customize according to your needs:
private void addNetworkAndServerErrorListener() {
// The following way to manage network errors is discussed here:
// https://stackoverflow.com/questions/61993127/distinguish-between-server-side-errors-and-connection-problems
addNetworkErrorListener(err -> {
// prevents the event from propagating
err.consume();
if (err.getError() != null) {
// this is the case of a network error,
// like: java.io.IOException: Unreachable
Log.p("Error connectiong to: " + err.getConnectionRequest().getUrl(), Log.ERROR);
// maybe there are connectivity issues, let's try again
ToastBar.showInfoMessage("Reconnect...");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
err.getConnectionRequest().retry();
}
}, 2000);
} else {
// this is the case of a server error
// logs the error
String errorLog = "REST ERROR\nURL:" + err.getConnectionRequest().getUrl()
+ "\nMethod: " + err.getConnectionRequest().getHttpMethod()
+ "\nResponse code: " + err.getConnectionRequest().getResponseCode();
if (err.getConnectionRequest().getRequestBody() != null) {
errorLog += "\nRequest body: " + err.getConnectionRequest().getRequestBody();
}
if (err.getMetaData() != null) {
errorLog += "\nMetaData: " + err.getMetaData().toString();
}
if (err.getConnectionRequest().getResponseData() != null) {
errorLog += "\nResponse message: " + new String(err.getConnectionRequest().getResponseData());
}
if (err.getConnectionRequest().getResponseErrorMessage() != null) {
errorLog += "\nResponse error message: " + err.getConnectionRequest().getResponseErrorMessage();
}
if (err.getMessage() != null) {
errorLog += "\nResponse error message: " + err.getMessage();
}
Log.p(errorLog, Log.ERROR);
Log.sendLogAsync();
ToastBar.showErrorMessage("Server Error", 10000);
}
});
}
Upvotes: 2