AbstractCloudBigtableTableDoFn extends DoFn<In, Out> { public static void logRetriesExhaustedWithDetailsException( Logger log, String context, RetriesExhaustedWithDetailsException exception) { if (log.isDebugEnabled()) { log.error( "For context {}: exception occurred during a bulk operation: {}", context, exception.getExhaustiveDescription()); } if (exception.getNumExceptions() == 0) { log.error( "For context {}: Got a RetriesExhaustedWithDetailsException without any details.", exception); return; } log.error( String.format( "For context %s: %d exceptions occurred during a bulk operation:\n\t%s.\n" + "The stack trace is a sample exception, of the first exception.\n" + "Breakdown of exceptions {type - count}: %s", context, exception.getNumExceptions(), exception.getMessage(), getFurtherInfo(exception)), exception.getCause(0)); } AbstractCloudBigtableTableDoFn(CloudBigtableConfiguration config); static void logRetriesExhaustedWithDetailsException(
      Logger log, String context, RetriesExhaustedWithDetailsException exception); @Override void populateDisplayData(DisplayData.Builder builder); CloudBigtableConfiguration getConfig();  }
@Test public void testLogRetriesExhaustedWithDetailsException() { Logger log = LoggerFactory.getLogger(getClass()); List<Throwable> exceptions = new ArrayList<>(); List<Row> actions = new ArrayList<>(); List<String> hostnameAndPort = new ArrayList<>(); for (int i = 0; i < 5; i++) { exceptions.add(Status.CANCELLED.asException()); actions.add(new Get(RandomStringUtils.randomAlphabetic(8).getBytes())); hostnameAndPort.add(""); } AbstractCloudBigtableTableDoFn.logRetriesExhaustedWithDetailsException( log, null, new RetriesExhaustedWithDetailsException(exceptions, actions, hostnameAndPort)); }