Source:
<code>private Future<TaskResult> checkAndSubmitNextTask(List<Shard> latestShards) { Future<TaskResult> submittedTaskFuture = null; if ((future == null) || future.isCancelled() || future.isDone()) { if ((future != null) && future.isDone()) { try { TaskResult result = future.get(); if (result.getException() != null) { LOG.error("Caught exception running " + currentTask.getTaskType() + " task: ", result.getException()); } } catch (InterruptedException | ExecutionException e) { LOG.warn(currentTask.getTaskType() + " task encountered exception.", e); } } currentTask = new MetricsCollectingTaskDecorator( new ShardSyncTask(kinesisProxy, leaseManager, initialPositionInStream, cleanupLeasesUponShardCompletion, ignoreUnexpectedChildShards, shardSyncIdleTimeMillis, shardSyncer, latestShards), metricsFactory); future = CompletableFuture.supplyAsync(() -> currentTask.call(), executorService) .whenComplete((taskResult, exception) -> { if (exception != null) { LOG.error("Caught exception running " + currentTask.getTaskType() + " task: ", exception); } try { lock.lock(); if (shardSyncRequestPending.get()) { shardSyncRequestPending.set(false); future = null; checkAndSubmitNextTask(latestShards); <START> } <END> } finally { lock.unlock(); } }); if (LOG.isDebugEnabled()) { LOG.debug("Submitted new " + currentTask.getTaskType() + " task."); } submittedTaskFuture = future; } else { if (LOG.isDebugEnabled()) { LOG.debug("Previous " + currentTask.getTaskType() + " task still pending. Not submitting new task. " + "Enqueued a request that will be executed when the current request completes."); } shardSyncRequestPending.compareAndSet(false , true ); } return submittedTaskFuture; }</code><technical_language>do need a catch block catch exceptions? For example, if fails acquire lock, helpful add a debug log for future debug needs</technical_language>

Target:
private Future<TaskResult> checkAndSubmitNextTask(List<Shard> latestShards) { Future<TaskResult> submittedTaskFuture = null; if ((future == null) || future.isCancelled() || future.isDone()) { if ((future != null) && future.isDone()) { try { TaskResult result = future.get(); if (result.getException() != null) { LOG.error("Caught exception running " + currentTask.getTaskType() + " task: ", result.getException()); } } catch (InterruptedException | ExecutionException e) { LOG.warn(currentTask.getTaskType() + " task encountered exception.", e); } } currentTask = new MetricsCollectingTaskDecorator( new ShardSyncTask(kinesisProxy, leaseManager, initialPositionInStream, cleanupLeasesUponShardCompletion, ignoreUnexpectedChildShards, shardSyncIdleTimeMillis, shardSyncer, latestShards), metricsFactory); future = CompletableFuture.supplyAsync(() -> currentTask.call(), executorService) .whenComplete((taskResult, exception) -> handlePendingShardSyncs(latestShards, exception)); if (LOG.isDebugEnabled()) { LOG.debug("Submitted new " + currentTask.getTaskType() + " task."); } submittedTaskFuture = future; } else { if (LOG.isDebugEnabled()) { LOG.debug("Previous " + currentTask.getTaskType() + " task still pending. Not submitting new task. " + "Enqueued a request that will be executed when the current request completes."); } shardSyncRequestPending.compareAndSet(false , true ); } return submittedTaskFuture; }