From e8adfa2c6e5bd421ab60983030a9e08c2468ea3b Mon Sep 17 00:00:00 2001 From: Olivier Lepage-Applin Date: Tue, 12 Aug 2025 12:42:08 -0400 Subject: [PATCH 1/3] fix potential NullPointerException in ApiCallAttemptTimeoutTrackingStage when exception is thrown before the tracker can be set in the context --- .../pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java index ca93b3572795..54334549020b 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java @@ -111,7 +111,8 @@ private Exception translatePipelineException(RequestExecutionContext context, Ex // but before we called timeoutTracker.cancel(). Note that if hasExecuted() returns true, its guaranteed that // the timeout tracker has set the interrupt flag, and if it returns false, it guarantees that it did not and // will never set the interrupt flag. - if (context.apiCallAttemptTimeoutTracker().hasExecuted()) { + TimeoutTracker timeoutTracker = context.apiCallAttemptTimeoutTracker(); + if (timeoutTracker != null && timeoutTracker.hasExecuted()) { // Clear the interrupt flag. Since we already have an exception from the call, which may contain information // that's useful to the caller, just return that instead of an ApiCallTimeoutException. Thread.interrupted(); @@ -136,7 +137,8 @@ private RuntimeException handleInterruptedException(RequestExecutionContext cont "Failed to close the response stream", r::close)); } - if (context.apiCallAttemptTimeoutTracker().hasExecuted()) { + TimeoutTracker timeoutTracker = context.apiCallAttemptTimeoutTracker(); + if (timeoutTracker != null && timeoutTracker.hasExecuted()) { // Clear the interrupt status Thread.interrupted(); return generateApiCallAttemptTimeoutException(context); From 19336d61f1a9826698d92b9a033cd5c934e43068 Mon Sep 17 00:00:00 2001 From: Olivier Lepage-Applin Date: Tue, 12 Aug 2025 12:53:17 -0400 Subject: [PATCH 2/3] changelog --- .changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json b/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json new file mode 100644 index 000000000000..ab7da2962b70 --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "", + "description": "Fix a potential NullPointerException in ApiCallAttemptTimeoutTrackingStage where the RequestExecutionContext might not have a timeout tracker configured" +} From ca4f63554beb469595ac5bbcb4055aa471e6e61c Mon Sep 17 00:00:00 2001 From: Olivier Lepage-Applin Date: Fri, 15 Aug 2025 13:21:56 -0400 Subject: [PATCH 3/3] updated changelog description --- .changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json b/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json index ab7da2962b70..3da5e47db3d0 100644 --- a/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json @@ -2,5 +2,5 @@ "type": "bugfix", "category": "AWS SDK for Java v2", "contributor": "", - "description": "Fix a potential NullPointerException in ApiCallAttemptTimeoutTrackingStage where the RequestExecutionContext might not have a timeout tracker configured" + "description": "Fix a potential NullPointerException that may be thrown when API call timeout is configured" }