1818
1919import static com .google .cloud .spanner .SpannerException .DoNotConstructDirectly ;
2020
21+ import com .google .api .gax .grpc .GrpcStatusCode ;
22+ import com .google .api .gax .rpc .ApiException ;
2123import com .google .common .base .MoreObjects ;
2224import com .google .common .base .Predicate ;
2325import io .grpc .Context ;
@@ -48,6 +50,11 @@ public static SpannerException propagateInterrupt(InterruptedException e) {
4850 return SpannerExceptionFactory .newSpannerException (ErrorCode .CANCELLED , "Interrupted" , e );
4951 }
5052
53+ public static SpannerException propagateTimeout (TimeoutException e ) {
54+ return SpannerExceptionFactory .newSpannerException (
55+ ErrorCode .DEADLINE_EXCEEDED , "Operation did not complete in the given time" , e );
56+ }
57+
5158 /**
5259 * Creates a new exception based on {@code cause}.
5360 *
@@ -71,6 +78,8 @@ public static SpannerException newSpannerException(@Nullable Context context, Th
7178 return newSpannerExceptionPreformatted (e .getErrorCode (), e .getMessage (), e );
7279 } else if (cause instanceof CancellationException ) {
7380 return newSpannerExceptionForCancellation (context , cause );
81+ } else if (cause instanceof ApiException ) {
82+ return fromApiException ((ApiException ) cause );
7483 }
7584 // Extract gRPC status. This will produce "UNKNOWN" for non-gRPC exceptions.
7685 Status status = Status .fromThrowable (cause );
@@ -120,6 +129,17 @@ private static SpannerException newSpannerExceptionPreformatted(
120129 }
121130 }
122131
132+ private static SpannerException fromApiException (ApiException exception ) {
133+ Status .Code code = ((GrpcStatusCode ) exception .getStatusCode ()).getTransportCode ();
134+ ErrorCode errorCode = ErrorCode .fromGrpcStatus (Status .fromCode (code ));
135+ if (exception .getCause () != null ) {
136+ return SpannerExceptionFactory .newSpannerException (
137+ errorCode , exception .getMessage (), exception .getCause ());
138+ } else {
139+ return SpannerExceptionFactory .newSpannerException (errorCode , exception .getMessage ());
140+ }
141+ }
142+
123143 private static boolean isRetryable (ErrorCode code , @ Nullable Throwable cause ) {
124144 switch (code ) {
125145 case INTERNAL :
0 commit comments