Skip to content

Commit

Permalink
Fixed an issue that could result in uncompletable future when headObj…
Browse files Browse the repository at this point in the history
…ect request threw exception in copy (#3609)
  • Loading branch information
zoewangg committed Dec 12, 2022
1 parent b257950 commit 3e64224
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,23 @@ public CompletableFuture<CopyObjectResponse> copyObject(CopyObjectRequest copyOb

CompletableFuture<CopyObjectResponse> returnFuture = new CompletableFuture<>();

CompletableFuture<HeadObjectResponse> headFuture =
s3AsyncClient.headObject(CopyRequestConversionUtils.toHeadObjectRequest(copyObjectRequest));

// Ensure cancellations are forwarded to the head future
CompletableFutureUtils.forwardExceptionTo(returnFuture, headFuture);

headFuture.whenComplete((headObjectResponse, throwable) -> {
if (throwable != null) {
handleException(returnFuture, () -> "Failed to retrieve metadata from the source object", throwable);
} else {
doCopyObject(copyObjectRequest, returnFuture, headObjectResponse);
}
});
try {
CompletableFuture<HeadObjectResponse> headFuture =
s3AsyncClient.headObject(CopyRequestConversionUtils.toHeadObjectRequest(copyObjectRequest));

// Ensure cancellations are forwarded to the head future
CompletableFutureUtils.forwardExceptionTo(returnFuture, headFuture);

headFuture.whenComplete((headObjectResponse, throwable) -> {
if (throwable != null) {
handleException(returnFuture, () -> "Failed to retrieve metadata from the source object", throwable);
} else {
doCopyObject(copyObjectRequest, returnFuture, headObjectResponse);
}
});
} catch (Throwable throwable) {
returnFuture.completeExceptionally(throwable);
}

return returnFuture;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ void copyObject_HeadObjectRequestFailed_shouldFail() {
.hasRootCause(exception);
}

@Test
void copyObject_HeadObjectRequestThrowsException_shouldFail() {
RuntimeException exception = new RuntimeException("oops");

when(s3AsyncClient.headObject(any(HeadObjectRequest.class)))
.thenThrow(exception);

CompletableFuture<CopyObjectResponse> future =
copyHelper.copyObject(copyObjectRequest());

assertThatThrownBy(future::join).hasCause(exception);
}

@Test
void singlePartCopy_happyCase_shouldSucceed() {

Expand Down

0 comments on commit 3e64224

Please sign in to comment.