How to deal with network issues

793 views Asked by At

One of my apps uses a lot of HTTP requests to communicate with its back-end. I use 2 different implementations to perform these requests:

  • The library Volley for most cases
  • A combination of AsyncTask and DefaultHttpClient for few cases

Most of the time, everything works well. But sometimes I have a bunch of network exceptions raised and shown into Crashlytics:

  • java.net.UnknownHostException: Unable to resolve host "mydomain.com": No address associated with hostname Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname)

  • com.android.volley.ServerError at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:175) at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)

With a bit of research, I found that this is supposed to happen when the device has a really bad 3g/4g or behind a VPN/subnetwork so it can't reach my website.

How do I make sure the device is really connected to internet? I actually perform these requests only if this function return true:

public static boolean isOnline(Context ctx) {
        ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        }
        return false;
}

Or should I just let it go and assume it is normal to get up to few hundreds of these warning per month?

3

There are 3 answers

0
FriendlyAgent On

In order to see if you have internet you have to do something more than check if you have a network connection. Because if your connected to a slow network, captive portal or a VPN you have a connection to the network but no actual internet or usable internet.

That's why you still need to check if you have internet/usable internet before you make a HTTP request by adding a simple ping to a server or Google (Because Google is up 99,99% of the time). You can also do it periodically or when you catch the first exception, that's up to you.

public Boolean isInternet() {
    try {       
        Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");      
        int returnVal = process.waitFor();      
        boolean reachable = (returnVal==0);
        return reachable
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false; 
}

You can also use another method but the general idea is the same use something you know is almost always online and check if you can reach it.

However keep handling exceptions, because there is no way to always catch it and having a back up way of handling things can't hurt

2
elmorabea On

Yes you should check internet availability before making an HTTP request, it saves a lot for you.

The code you should is very good and far better than "pinging" any domain.

But still in your case your condition isn't going to be sufficient, because the adapter is actually connected but you may not be able to connect to your server due to poor connection.

So you should still handle time-out and IO exceptions that might happen while you're executing your requests.

-- Set time out for your Httpclient -- and i think volley by default has a timeout.

0
user207421 On

How do I make sure the device is really connected to internet?

You have found out. That's what the errors are telling you.

How do I make sure the device is really connected to internet? I actually perform these requests only if this function return true:

I'm not in favour of this sort of thing:

  • if it tests exactly the same things as the actual request does, it is (i) duplicated work and (ii) not done at the same time
  • if it doesn't test exactly the same things as the actual request, you are likely to get both false positives and false negatives
  • in all cases, it's an attempt to predict the future. It might fail now and the request succeed, or succeed now and the request fail.
  • you have to write the error handling code for the request anyway.

In general the best way to test whether any resource is available is just to try to use it in the normal way, and deal with any adverse consequences as and when they arise.

Or should I just let it go and assume it is normal to get up to few hundreds of these warning per month?

I wouldn't say ServerError is normal. It's possible that the server managed to send that to you over a fully functioning network, so it may be a server or client bug you need to investigate. Network outages on the other hand are 'normal' in any topology and technology.