diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json b/.changes/next-release/bugfix-AWSSDKforJavav2-71c9a16.json new file mode 100644 index 000000000000..3da5e47db3d0 --- /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 that may be thrown when API call timeout is configured" +} 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);