@Override public Database apply(Exception e) { throw SpannerExceptionFactory.newSpannerException(e); } });
/** Gets the result of an async RPC call, handling any exceptions encountered. */ private static <T> T get(final Future<T> future) throws SpannerException { final Context context = Context.current(); try { return future.get(); } catch (InterruptedException e) { // We are the sole consumer of the future, so cancel it. future.cancel(true); throw SpannerExceptionFactory.propagateInterrupt(e); } catch (ExecutionException | CancellationException e) { throw newSpannerException(context, e); } }
public static SpannerException newSpannerException( ErrorCode code, @Nullable String message, @Nullable Throwable cause) { return newSpannerExceptionPreformatted(code, formatMessage(code, message), cause); }
/** * Creates a new exception based on {@code cause}. If {@code cause} indicates cancellation, {@code * context} will be inspected to establish the type of cancellation. * * <p>Intended for internal library use; user code should use {@link * #newSpannerException(ErrorCode, String)} instead of this method. */ public static SpannerException newSpannerException(@Nullable Context context, Throwable cause) { if (cause instanceof SpannerException) { SpannerException e = (SpannerException) cause; return newSpannerExceptionPreformatted(e.getErrorCode(), e.getMessage(), e); } else if (cause instanceof CancellationException) { return newSpannerExceptionForCancellation(context, cause); } // Extract gRPC status. This will produce "UNKNOWN" for non-gRPC exceptions. Status status = Status.fromThrowable(cause); if (status.getCode() == Status.Code.CANCELLED) { return newSpannerExceptionForCancellation(context, cause); } return newSpannerException(ErrorCode.fromGrpcStatus(status), cause.getMessage(), cause); }
/** Example to update the database DDL. */ // [TARGET updateDatabaseDdl(String, String, Iterable, String)] // [VARIABLE my_instance_id] // [VARIABLE my_database_id] public void updateDatabaseDdl(String instanceId, String databaseId) { // [START updateDatabaseDdl] try { dbAdminClient .updateDatabaseDdl( instanceId, databaseId, Arrays.asList("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"), null) .get(); } catch (ExecutionException e) { throw (SpannerException) e.getCause(); } catch (InterruptedException e) { throw SpannerExceptionFactory.propagateInterrupt(e); } // [END updateDatabaseDdl] }
/** * Checks that the current context is still valid, throwing a CANCELLED or DEADLINE_EXCEEDED error * if not. */ private static void checkContext(Context context) { if (context.isCancelled()) { throw newSpannerExceptionForCancellation(context, null); } }
private static SpannerException newSpannerExceptionPreformatted( ErrorCode code, @Nullable String message, @Nullable Throwable cause) { // This is the one place in the codebase that is allowed to call constructors directly. DoNotConstructDirectly token = DoNotConstructDirectly.ALLOWED; switch (code) { case ABORTED: return new AbortedException(token, message, cause); default: return new SpannerException(token, code, isRetryable(code, cause), message, cause); } }
private static boolean isRetryable(ErrorCode code, @Nullable Throwable cause) { switch (code) { case INTERNAL: return hasCauseMatching(cause, Matchers.isRetryableInternalError); case UNAVAILABLE: return true; case RESOURCE_EXHAUSTED: return SpannerException.extractRetryDelay(cause) > 0; default: return false; } }
throw (SpannerException) e.getCause(); } catch (InterruptedException e) { throw SpannerExceptionFactory.propagateInterrupt(e);
/** * Creates a new exception based on {@code cause}. If {@code cause} indicates cancellation, {@code * context} will be inspected to establish the type of cancellation. * * <p>Intended for internal library use; user code should use {@link * #newSpannerException(ErrorCode, String)} instead of this method. */ public static SpannerException newSpannerException(@Nullable Context context, Throwable cause) { if (cause instanceof SpannerException) { SpannerException e = (SpannerException) cause; return newSpannerExceptionPreformatted(e.getErrorCode(), e.getMessage(), e); } else if (cause instanceof CancellationException) { return newSpannerExceptionForCancellation(context, cause); } // Extract gRPC status. This will produce "UNKNOWN" for non-gRPC exceptions. Status status = Status.fromThrowable(cause); if (status.getCode() == Status.Code.CANCELLED) { return newSpannerExceptionForCancellation(context, cause); } return newSpannerException(ErrorCode.fromGrpcStatus(status), cause.getMessage(), cause); }
throw newSpannerExceptionForCancellation(context, null); throw newSpannerExceptionForCancellation(context, interruptExcept); } finally { context.removeListener(listener);
private static SpannerException newSpannerExceptionPreformatted( ErrorCode code, @Nullable String message, @Nullable Throwable cause) { // This is the one place in the codebase that is allowed to call constructors directly. DoNotConstructDirectly token = DoNotConstructDirectly.ALLOWED; switch (code) { case ABORTED: return new AbortedException(token, message, cause); default: return new SpannerException(token, code, isRetryable(code, cause), message, cause); } }
private static boolean isRetryable(ErrorCode code, @Nullable Throwable cause) { switch (code) { case INTERNAL: return hasCauseMatching(cause, Matchers.isRetryableInternalError); case UNAVAILABLE: return true; case RESOURCE_EXHAUSTED: return SpannerException.extractRetryDelay(cause) > 0; default: return false; } }
@Override public Instance apply(Exception e) { throw SpannerExceptionFactory.newSpannerException(e); } });
@Override protected final PartialResultSet computeNext() { PartialResultSet next; try { // TODO: Ideally honor io.grpc.Context while blocking here. In practice, // cancellation/deadline results in an error being delivered to "stream", which // should mean that we do not block significantly longer afterwards, but it would // be more robust to use poll() with a timeout. next = stream.take(); } catch (InterruptedException e) { // Treat interrupt as a request to cancel the read. throw SpannerExceptionFactory.propagateInterrupt(e); } if (next != END_OF_STREAM) { call.request(1); return next; } // All done - close() no longer needs to cancel the call. call = null; if (error != null) { throw SpannerExceptionFactory.newSpannerException(error); } endOfData(); return null; }
throw (SpannerException) e.getCause(); } catch (InterruptedException e) { throw SpannerExceptionFactory.propagateInterrupt(e);
public static SpannerException newSpannerException( ErrorCode code, @Nullable String message, @Nullable Throwable cause) { return newSpannerExceptionPreformatted(code, formatMessage(code, message), cause); }
/** * Checks that the current context is still valid, throwing a CANCELLED or DEADLINE_EXCEEDED error * if not. */ private static void checkContext(Context context) { if (context.isCancelled()) { throw newSpannerExceptionForCancellation(context, null); } }
@Override public Instance apply(Exception e) { throw SpannerExceptionFactory.newSpannerException(e); } });
return Operation.create(rpc, proto, parser); } catch (InterruptedException e) { throw SpannerExceptionFactory.propagateInterrupt(e); } catch (ExecutionException e) { Throwable cause = e.getCause(); throw SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "Operation did not complete in the given time"); throw SpannerExceptionFactory.newSpannerException(cause);