class ApiErrorExtractor {

  public boolean socketError(Throwable throwable) {
    if (throwable instanceof SocketException || throwable instanceof SocketTimeoutException) {
      return true;
    }
    Throwable cause = throwable.getCause();
    // Subset of SSL exceptions that are caused by IO errors (e.g. SSLHandshakeException due to
    // unexpected connection closure) is also a socket error.
    if (throwable instanceof SSLException && cause != null && ioError(cause)) {
      return true;
    }
    return cause != null && socketError(cause);
  }

}