Why retryOnConnectionFailure(true) Is a Solution to Okhttp Error: Java. Io. Ioexception: Unexpected End of Stream

I had this error for quite a while now when i found this. After using the solution provided by swankjesse the error disappeared. I just cant seem to understand why this is a solution. I cant find anything online that explains the reason why this method solves the error.

OkHttp Docs say:

retryOnConnectionFailure

Configure this client to retry or not when a connectivity problem is encountered. By default, this client silently recovers from the following problems:

Unreachable IP addresses. If the URL’s host has multiple IP addresses, failure to reach any individual IP address doesn’t fail the overall request. This can increase availability of multi-homed services.

Stale pooled connections. The ConnectionPool reuses sockets to decrease request latency, but these connections will occasionally time out.

Unreachable proxy servers. A ProxySelector can be used to attempt multiple proxy servers in sequence, eventually falling back to a direct connection.

The above is understandable but it does not justify why this is a solution to that error.

Thanks in advance.

This flag allows OkHttpClient to retry a request multiple times when certain conditions are true that mean it is known to be safe. Without this flag the client will return the error immediately for the client to presumably dcide if and when to retry.

  private fun isRecoverable(e: IOException, requestSendStarted: Boolean): Boolean {
    // If there was a protocol problem, don't recover.
    if (e is ProtocolException) {
      return false
    }

    // If there was an interruption don't recover, but if there was a timeout connecting to a route
    // we should try the next route (if there is one).
    if (e is InterruptedIOException) {
      return e is SocketTimeoutException && !requestSendStarted
    }

    // Look for known client-side or negotiation errors that are unlikely to be fixed by trying
    // again with a different route.
    if (e is SSLHandshakeException) {
      // If the problem was a CertificateException from the X509TrustManager,
      // do not retry.
      if (e.cause is CertificateException) {
        return false
      }
    }
    if (e is SSLPeerUnverifiedException) {
      // e.g. a certificate pinning error.
      return false
    }
    // An example of one we might want to retry with a different route is a problem connecting to a
    // proxy and would manifest as a standard IOException. Unless it is one we know we should not
    // retry, we return true and try a new route.
    return true
  }

In the most simple case, if we hadn't started sending a request then we know retrying must be safe. Likewise certain response codes like 408 indicate that the server hasn't started any work so we can try again.

0
Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article