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 39978102e263..f6f6210d85e7 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 @@ -18,6 +18,8 @@ import static com.google.cloud.spanner.SpannerException.DoNotConstructDirectly; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.rpc.ApiException; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import io.grpc.Context; @@ -48,6 +50,28 @@ public static SpannerException propagateInterrupt(InterruptedException e) { return SpannerExceptionFactory.newSpannerException(ErrorCode.CANCELLED, "Interrupted", e); } + /** + * Transforms a {@code TimeoutException} to a {@code SpannerException}. + * + *
+ *
+ * try {
+ * Spanner spanner = SpannerOptions.getDefaultInstance();
+ * spanner
+ * .getDatabaseAdminClient()
+ * .createDatabase("[INSTANCE_ID]", "[DATABASE_ID]", [STATEMENTS])
+ * .get();
+ * } catch (TimeoutException e) {
+ * propagateTimeout(e);
+ * }
+ *
+ *
+ */
+ public static SpannerException propagateTimeout(TimeoutException e) {
+ return SpannerExceptionFactory.newSpannerException(
+ ErrorCode.DEADLINE_EXCEEDED, "Operation did not complete in the given time", e);
+ }
+
/**
* Creates a new exception based on {@code cause}.
*
@@ -71,6 +95,8 @@ public static SpannerException newSpannerException(@Nullable Context context, Th
return newSpannerExceptionPreformatted(e.getErrorCode(), e.getMessage(), e);
} else if (cause instanceof CancellationException) {
return newSpannerExceptionForCancellation(context, cause);
+ } else if (cause instanceof ApiException) {
+ return fromApiException((ApiException) cause);
}
// Extract gRPC status. This will produce "UNKNOWN" for non-gRPC exceptions.
Status status = Status.fromThrowable(cause);
@@ -120,6 +146,17 @@ private static SpannerException newSpannerExceptionPreformatted(
}
}
+ private static SpannerException fromApiException(ApiException exception) {
+ Status.Code code = ((GrpcStatusCode) exception.getStatusCode()).getTransportCode();
+ ErrorCode errorCode = ErrorCode.fromGrpcStatus(Status.fromCode(code));
+ if (exception.getCause() != null) {
+ return SpannerExceptionFactory.newSpannerException(
+ errorCode, exception.getMessage(), exception.getCause());
+ } else {
+ return SpannerExceptionFactory.newSpannerException(errorCode, exception.getMessage());
+ }
+ }
+
private static boolean isRetryable(ErrorCode code, @Nullable Throwable cause) {
switch (code) {
case INTERNAL: