@Override public V apply(ApiException exception) { if (returnNullOnSet.contains(exception.getStatusCode().getCode())) { return null; } throw new LoggingException(exception); } });
@Override public void onFailure(Throwable throwable) { if (throwable instanceof ApiException) { ApiException apiException = ((ApiException) throwable); // details on the API exception System.out.println(apiException.getStatusCode().getCode()); System.out.println(apiException.isRetryable()); } System.out.println("Error publishing message : " + message); }
@Override public void run() { listener.onEvent( null, throwable instanceof FirestoreException ? (FirestoreException) throwable : FirestoreException.apiException( new ApiException( throwable, GrpcStatusCode.of(getStatus(throwable).getCode()), false))); } });
public static boolean isRetryable(Throwable error) { if (!(error instanceof ApiException)) { return true; } ApiException apiException = (ApiException) error; switch (apiException.getStatusCode().getCode()) { case DEADLINE_EXCEEDED: case INTERNAL: case CANCELLED: case RESOURCE_EXHAUSTED: case ABORTED: return true; case UNAVAILABLE: // TODO(pongad): check that ApiException propagate message properly. return !apiException.getMessage().contains("Server shutdownNow invoked"); default: return false; } } }
@BetaApi public BaseGrpcServiceException(ApiException apiException) { super( ExceptionData.newBuilder() .setMessage(apiException.getMessage()) .setCause(apiException) .setRetryable(apiException.isRetryable()) .setCode(apiException.getStatusCode().getCode().getHttpStatusCode()) .setReason(apiException.getStatusCode().getCode().name()) .setLocation(null) .setDebugInfo(null) .build()); } }
@Override public boolean shouldRetry(Throwable prevThrowable, ResponseT prevResponse) { return (prevThrowable instanceof ApiException) && ((ApiException) prevThrowable).isRetryable(); } }
assertThat(failedMutations.get(0).getError().isRetryable()).isFalse(); assertThat(failedMutations.get(0).getError().getCause()).isEqualTo(rpcError); assertThat(failedMutations.get(1).getError().isRetryable()).isFalse(); assertThat(failedMutations.get(1).getError().getCause()).isEqualTo(rpcError);
logger.warn("failed to send metrics to stackdriver: {}", e.getCause().getMessage());
public static Status statusFromApiException(ApiException exception) { if (exception.getStatusCode().getTransportCode() instanceof io.grpc.Status) { io.grpc.Status grpcStatus = (io.grpc.Status) exception.getStatusCode().getTransportCode(); return StatusConverter.fromGrpcStatus(grpcStatus); } return Status.UNKNOWN.withDescription(exception.getMessage()); } }
@BetaApi public BaseGrpcServiceException(ApiException apiException) { super( ExceptionData.newBuilder() .setMessage(apiException.getMessage()) .setCause(apiException) .setRetryable(apiException.isRetryable()) .setCode(apiException.getStatusCode().getCode().getHttpStatusCode()) .setReason(apiException.getStatusCode().getCode().name()) .setLocation(null) .setDebugInfo(null) .build()); } }
/** * Handle an RPC level failure by generating a {@link FailedMutation} for each expected entry. The * newly generated {@link FailedMutation}s will be combined with the permanentFailures to give the * caller the whole picture since the first call. This method will always throw a {@link * MutateRowsException}. */ private void handleAttemptError(Throwable rpcError) { ApiException entryError = createSyntheticErrorForRpcFailure(rpcError); ImmutableList.Builder<FailedMutation> allFailures = ImmutableList.builder(); MutateRowsRequest lastRequest = currentRequest; allFailures.addAll(permanentFailures); Builder builder = lastRequest.toBuilder().clearEntries(); List<Integer> newOriginalIndexes = Lists.newArrayList(); for (int i = 0; i < currentRequest.getEntriesCount(); i++) { int origIndex = getOriginalIndex(i); FailedMutation failedMutation = FailedMutation.create(origIndex, entryError); allFailures.add(failedMutation); if (!failedMutation.getError().isRetryable()) { permanentFailures.add(failedMutation); } else { // Schedule the mutation entry for the next RPC by adding it to the request builder and // recording its original index newOriginalIndexes.add(origIndex); builder.addEntries(lastRequest.getEntries(i)); } } currentRequest = builder.build(); originalIndexes = newOriginalIndexes; throw new MutateRowsException(rpcError, allFailures.build(), entryError.isRetryable()); }
assertThat(failedMutations.get(0).getError().isRetryable()).isTrue(); assertThat(failedMutations.get(0).getError().getCause()).isEqualTo(rpcError); assertThat(failedMutations.get(1).getError().isRetryable()).isTrue(); assertThat(failedMutations.get(1).getError().getCause()).isEqualTo(rpcError);
private void createMetricDescriptorIfNecessary(MetricServiceClient client, Meter.Id id, MetricDescriptor.ValueType valueType, @Nullable String statistic) { if (!verifiedDescriptors.contains(id.getName())) { MetricDescriptor descriptor = MetricDescriptor.newBuilder() .setType(metricType(id, statistic)) .setDescription(id.getDescription() == null ? "" : id.getDescription()) .setMetricKind(MetricDescriptor.MetricKind.GAUGE) .setValueType(valueType) .build(); ProjectName name = ProjectName.of(config.projectId()); CreateMetricDescriptorRequest request = CreateMetricDescriptorRequest.newBuilder() .setName(name.toString()) .setMetricDescriptor(descriptor) .build(); if (logger.isTraceEnabled()) { logger.trace("creating metric descriptor:\n{}", request); } try { client.createMetricDescriptor(request); verifiedDescriptors.add(id.getName()); } catch (ApiException e) { logger.warn("failed to create metric descriptor in stackdriver for meter " + id + " {}", e.getCause().getMessage()); } } }
@SuppressWarnings("ConstantConditions") private void verifyError(ApiFuture<?> result, StatusCode.Code expectedCode) { Throwable error = null; try { result.get(FLUSH_PERIOD.plus(DELAY_BUFFER).toMillis(), TimeUnit.MILLISECONDS); } catch (ExecutionException e) { error = e.getCause(); } catch (Throwable t) { error = t; } assertThat(error).isInstanceOf(ApiException.class); assertThat(((ApiException) error).getStatusCode().getCode()).isEqualTo(expectedCode); }
/** * Create a synthetic {@link ApiException} for an individual entry. When the entire RPC fails, it * implies that all entries failed as well. This helper is used to make that behavior explicit. * The generated exception will have the overall error as its cause. */ private static ApiException createSyntheticErrorForRpcFailure(Throwable overallRequestError) { if (overallRequestError instanceof ApiException) { ApiException requestApiException = (ApiException) overallRequestError; return ApiExceptionFactory.createException( "Didn't receive a result for this mutation entry", overallRequestError, requestApiException.getStatusCode(), requestApiException.isRetryable()); } return ApiExceptionFactory.createException( "Didn't receive a result for this mutation entry", overallRequestError, LOCAL_UNKNOWN_STATUS, false); } }
public static Status statusFromApiException(ApiException exception) { if (exception.getStatusCode().getTransportCode() instanceof io.grpc.Status) { io.grpc.Status grpcStatus = (io.grpc.Status) exception.getStatusCode().getTransportCode(); return StatusConverter.fromGrpcStatus(grpcStatus); } return Status.UNKNOWN.withDescription(exception.getMessage()); } }
if (!failedMutation.getError().isRetryable()) { permanentFailures.add(failedMutation); } else {
@Test public void testIsRetryable() { assertThat( StatusUtil.isRetryable( new ApiException("derp", null, GrpcStatusCode.of(Code.UNAVAILABLE), false))) .isTrue(); assertThat( StatusUtil.isRetryable( new ApiException( "Server shutdownNow invoked", null, GrpcStatusCode.of(Code.UNAVAILABLE), false))) .isFalse(); } }
@Test(expected = IllegalStateException.class) public void testFailedChannel_fatalError_subscriberFails() throws Exception { Subscriber subscriber = startSubscriber( getTestSubscriberBuilder(testReceiver) .setSystemExecutorProvider( InstantiatingExecutorProvider.newBuilder().setExecutorThreadCount(10).build())); // Fatal error fakeSubscriberServiceImpl.sendError(new StatusException(Status.INVALID_ARGUMENT)); try { subscriber.awaitTerminated(); } finally { // The subscriber must finish with an state error because its FAILED status. assertEquals(Subscriber.State.FAILED, subscriber.state()); Throwable t = subscriber.failureCause(); assertTrue(t instanceof ApiException); ApiException ex = (ApiException) (t); assertTrue(ex.getStatusCode() instanceof GrpcStatusCode); GrpcStatusCode grpcCode = (GrpcStatusCode) ex.getStatusCode(); assertEquals(StatusCode.Code.INVALID_ARGUMENT, grpcCode.getCode()); } }
assertThat(failedMutations.get(0).getError().getStatusCode().getCode()) .isEqualTo(Code.UNAVAILABLE); assertThat(failedMutations.get(0).getError().isRetryable()).isTrue(); assertThat(failedMutations.get(1).getError().getStatusCode().getCode()) .isEqualTo(Code.INVALID_ARGUMENT); assertThat(failedMutations.get(1).getError().isRetryable()).isFalse();