diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java index 1c350f063a..1a415681f0 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java @@ -177,19 +177,14 @@ private CompletableFuture retryWithExponentialBackoff( } } } else { - final Throwable finalThrowable; - if (throwable instanceof CompletionException) { - finalThrowable = throwable.getCause(); - } else { - finalThrowable = throwable; - } - builder.interceptors.forEach((s, interceptor) -> interceptor.afterConnectionFailure(request, finalThrowable)); - if (finalThrowable instanceof IOException) { + final Throwable actualCause = unwrapCompletionException(throwable); + builder.interceptors.forEach((s, interceptor) -> interceptor.afterConnectionFailure(request, actualCause)); + if (actualCause instanceof IOException) { // TODO: may not be specific enough - incorrect ssl settings for example will get caught here LOG.debug( String.format("HTTP operation on url: %s should be retried after %d millis because of IOException", uri, retryInterval), - finalThrowable); + actualCause); return true; } } @@ -197,6 +192,16 @@ private CompletableFuture retryWithExponentialBackoff( }); } + static Throwable unwrapCompletionException(Throwable throwable) { + final Throwable actualCause; + if (throwable instanceof CompletionException) { + actualCause = throwable.getCause(); + } else { + actualCause = throwable; + } + return actualCause; + } + static long retryAfterMillis(HttpResponse httpResponse) { String retryAfter = httpResponse.header(StandardHttpHeaders.RETRY_AFTER); if (retryAfter != null) { diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java index 038ceed414..387f6aefac 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java @@ -34,6 +34,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -50,6 +51,7 @@ class StandardHttpClientTest { + public static final String IO_ERROR_MESSAGE = "IO woopsie"; private TestStandardHttpClient client; @BeforeEach @@ -281,4 +283,26 @@ void testDerivedIsClosed() { assertTrue(client.isClosed()); } + @Test + void shouldUnwrapCompletionException() { + // Given + + // When + final Throwable throwable = StandardHttpClient + .unwrapCompletionException(new CompletionException(new IOException(IO_ERROR_MESSAGE))); + + // Then + assertThat(throwable).isInstanceOf(IOException.class).hasMessage(IO_ERROR_MESSAGE); + } + + @Test + void shouldNotUnwrapOtherExceptions() { + // Given + + // When + final Throwable throwable = StandardHttpClient.unwrapCompletionException(new IOException(IO_ERROR_MESSAGE)); + + // Then + assertThat(throwable).isInstanceOf(IOException.class).hasMessage(IO_ERROR_MESSAGE); + } }