From 84969fbdad0674b5db3d9e0215225a4f35b0854e Mon Sep 17 00:00:00 2001 From: Olav Loite Date: Fri, 8 Mar 2019 17:20:30 +0100 Subject: [PATCH] #3889 throw exception when an SSLHandshakeException occurs SSLHandshakeExceptions are not retryable, as it is most probably an indication that the client does not accept the server certificate. --- .../spanner/SpannerExceptionFactory.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java index 3ff2d6749778..0c90f05aae04 100644 --- a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java +++ b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java @@ -16,18 +16,18 @@ package com.google.cloud.spanner; -import static com.google.cloud.spanner.SpannerException.DoNotConstructDirectly; - +import java.util.concurrent.CancellationException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nullable; +import javax.net.ssl.SSLHandshakeException; import com.google.api.gax.grpc.GrpcStatusCode; import com.google.api.gax.rpc.ApiException; +import com.google.cloud.spanner.SpannerException.DoNotConstructDirectly; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import io.grpc.Context; import io.grpc.Status; import io.grpc.StatusRuntimeException; -import java.util.concurrent.CancellationException; -import java.util.concurrent.TimeoutException; -import javax.annotation.Nullable; /** * A factory for creating instances of {@link SpannerException} and its subtypes. All creation of @@ -168,7 +168,9 @@ private static boolean isRetryable(ErrorCode code, @Nullable Throwable cause) { case INTERNAL: return hasCauseMatching(cause, Matchers.isRetryableInternalError); case UNAVAILABLE: - return true; + // SSLHandshakeException is (probably) not retryable, as it is an indication that the server + // certificate was not accepted by the client. + return !hasCauseMatching(cause, Matchers.isSSLHandshakeException); case RESOURCE_EXHAUSTED: return SpannerException.extractRetryDelay(cause) > 0; default: @@ -211,5 +213,11 @@ public boolean apply(Throwable cause) { return false; } }; + static final Predicate isSSLHandshakeException = new Predicate() { + @Override + public boolean apply(Throwable input) { + return input instanceof SSLHandshakeException; + } + }; } }