HttpRequestExecutor { static boolean isTransientHttpException(Throwable e) { if (e instanceof NetworkException) { int responseCode = ((NetworkException) e).getResponseCode(); if (responseCode == STATUS_CONNECT_TIMEOUT) return true; if (responseCode == STATUS_READ_TIMEOUT) return true; if (responseCode >= 500 && responseCode <= 599) return true; } else if ( e instanceof SSLException || e instanceof SocketException || e instanceof SocketTimeoutException) { return true; } else if (e instanceof IOException && e.getMessage().startsWith("Unable to tunnel through proxy")) { return true; } return e.getCause() != null && isTransientHttpException(e.getCause()); } HttpRequestExecutor(Clock clock, NetworkConfig networkConfig); HttpRequest execute( NetworkRequester networkRequester ); int getMaxRetries(); void setMaxRetries(int maxRetries); int getSleepIntervalMillis(); void setSleepIntervalMillis(int sleepIntervalMillis); int getRetries();  }
@Test public void testTransientExceptions() { assertTrue(isTransientHttpException(new NetworkException("", 503))); assertTrue(isTransientHttpException(new NetworkException("", STATUS_CONNECT_TIMEOUT))); assertTrue(isTransientHttpException(new NetworkException("", STATUS_READ_TIMEOUT))); assertTrue(isTransientHttpException(new SSLException(""))); assertTrue(isTransientHttpException(new RuntimeException(new NetworkException("", 503)))); assertTrue(isTransientHttpException(new SocketTimeoutException(""))); assertTrue(isTransientHttpException(new SocketException(""))); assertTrue(isTransientHttpException(new NetworkException("", new SocketTimeoutException("")))); }
@Test public void testWithTunnelFailure() throws Exception { assertTrue(isTransientHttpException(new IOException("Unable to tunnel through proxy. Proxy returns \"HTTP/1.0 503 Service Unavailable\""))); assertTrue(isTransientHttpException(new NetworkException("", new IOException("Unable to tunnel through proxy. Proxy returns \"HTTP/1.0 503 Service Unavailable\"")))); }
@Test public void testFatalNetworkExceptions() throws Exception { assertFalse(isTransientHttpException(new NetworkException("", 404))); assertFalse(isTransientHttpException(new RuntimeException())); assertFalse(isTransientHttpException(new RuntimeException(new NetworkException("", 404)))); }
@Test public void testSSLHandshakeException() throws Exception { assertTrue(isTransientHttpException(new SSLHandshakeException("Remote host closed connection during handshake"))); }