From 821397a4c3bf173ffa81541eaefbfa265b3d89e4 Mon Sep 17 00:00:00 2001 From: David Ho <70000000+davidh44@users.noreply.github.com> Date: Wed, 21 Sep 2022 09:15:21 -0700 Subject: [PATCH] Errors should not be wrapped - Http (#3431) * Errors should not be wrapped - Http * Changelog entry * Cast Throwable to Exception * instance check of Exception * Refactor instance check --- .../bugfix-AWSSDKforJavav2-ee04822.json | 6 ++++++ .../pipeline/stages/AsyncRetryableStage.java | 8 ++++++-- .../AsyncRetryableStageAdaptiveModeTest.java | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-ee04822.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-ee04822.json b/.changes/next-release/bugfix-AWSSDKforJavav2-ee04822.json new file mode 100644 index 000000000000..9e0c172cc5e7 --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-ee04822.json @@ -0,0 +1,6 @@ +{ + "category": "AWS SDK for Java v2", + "contributor": "", + "type": "bugfix", + "description": "Fixed issue where errors were being wrapped by SdkClientException" +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStage.java index c5134402e6e2..18c3103d204e 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStage.java @@ -156,7 +156,11 @@ private void attemptExecute(CompletableFuture> future) { responseFuture.whenComplete((response, exception) -> { if (exception != null) { - maybeRetryExecute(future, exception); + if (exception instanceof Exception) { + maybeRetryExecute(future, (Exception) exception); + } else { + future.completeExceptionally(exception); + } return; } @@ -175,7 +179,7 @@ private void attemptExecute(CompletableFuture> future) { }); } - private void maybeRetryExecute(CompletableFuture> future, Throwable exception) { + private void maybeRetryExecute(CompletableFuture> future, Exception exception) { retryableStageHelper.setLastException(exception); retryableStageHelper.updateClientSendingRateForErrorResponse(); maybeAttemptExecute(future); diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStageAdaptiveModeTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStageAdaptiveModeTest.java index 40bfeacf1db9..cf40f145a42e 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStageAdaptiveModeTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncRetryableStageAdaptiveModeTest.java @@ -192,6 +192,21 @@ public void execute_throttlingServiceException_updatesRate() throws Exception { verify(tokenBucket, never()).updateClientSendingRate(false); } + @Test + public void execute_errorShouldNotBeWrapped() throws Exception { + RetryPolicy retryPolicy = RetryPolicy.builder(RetryMode.ADAPTIVE) + .numRetries(0) + .build(); + + mockChildResponse(new OutOfMemoryError()); + retryableStage = createStage(retryPolicy); + + SdkHttpFullRequest httpRequest = createHttpRequest(); + RequestExecutionContext executionContext = createExecutionContext(); + assertThatThrownBy(() -> retryableStage.execute(httpRequest, executionContext).join()) + .hasCauseInstanceOf(Error.class); + } + @Test public void execute_unsuccessfulResponse_nonThrottlingError_doesNotUpdateRate() throws Exception { @@ -298,4 +313,9 @@ private void mockChildResponse(Exception error) throws Exception { CompletableFuture> errorResult = CompletableFutureUtils.failedFuture(error); when(mockChildPipeline.execute(any(SdkHttpFullRequest.class), any(RequestExecutionContext.class))).thenReturn(errorResult); } + + private void mockChildResponse(Error error) throws Exception { + CompletableFuture> errorResult = CompletableFutureUtils.failedFuture(error); + when(mockChildPipeline.execute(any(SdkHttpFullRequest.class), any(RequestExecutionContext.class))).thenReturn(errorResult); + } }