-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: treat IO exceptions as retryable in HTTP engines #979
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"id": "0645c929-bdfe-4d07-a131-b0b447422fff", | ||
"type": "bugfix", | ||
"description": "Treat all IO errors in OkHttp & CRT engines as retryable (e.g., socket errors, DNS lookup failures, etc.)" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
...lient-engine-crt/common/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package aws.smithy.kotlin.runtime.http.engine.crt | ||
|
||
import kotlin.test.Test | ||
import kotlin.test.assertFalse | ||
import kotlin.test.assertTrue | ||
|
||
class RequestUtilTest { | ||
@Test | ||
fun testExceptionRetryability() { | ||
setOf( | ||
// All IO errors are retryable | ||
"AWS_IO_SOCKET_NETWORK_DOWN", | ||
"AWS_ERROR_IO_OPERATION_CANCELLED", | ||
"AWS_IO_DNS_NO_ADDRESS_FOR_HOST", | ||
|
||
// Any connection closure is retryable | ||
"AWS_ERROR_HTTP_CONNECTION_CLOSED", | ||
"AWS_ERROR_HTTP_SERVER_CLOSED", | ||
"AWS_IO_BROKEN_PIPE", | ||
|
||
// All proxy errors are retryable | ||
"AWS_ERROR_HTTP_PROXY_CONNECT_FAILED", | ||
"AWS_ERROR_HTTP_PROXY_STRATEGY_NTLM_CHALLENGE_TOKEN_MISSING", | ||
"AWS_ERROR_HTTP_PROXY_STRATEGY_TOKEN_RETRIEVAL_FAILURE", | ||
|
||
// Any connection manager issues are retryable | ||
"AWS_ERROR_HTTP_CONNECTION_MANAGER_INVALID_STATE_FOR_ACQUIRE", | ||
"AWS_ERROR_HTTP_CONNECTION_MANAGER_VENDED_CONNECTION_UNDERFLOW", | ||
"AWS_ERROR_HTTP_CONNECTION_MANAGER_SHUTTING_DOWN", | ||
).forEach { name -> assertTrue(isRetryable(name), "Expected $name to be retryable!") } | ||
|
||
setOf( | ||
// Any other errors are not retryable | ||
"AWS_ERROR_HTTP_INVALID_METHOD", | ||
"AWS_ERROR_PKCS11_CKR_CANCEL", | ||
"AWS_ERROR_PEM_MALFORMED", | ||
|
||
// Unknown error codes are not retryable | ||
null, | ||
).forEach { name -> assertFalse(isRetryable(name), "Expected $name to not be retryable!") } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question/Correctness: Is there any reason we wouldn't just make all
IOExceptions
retryable at the retry policy level?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few reasons came to mind:
IOException
isn't in Kotlin stdlib—it's a JVM exception. Our retry policy is currently in common code. We could introduce anexpect
/actual
function to dispatch down for platform-specific exceptions but it doesn't feel warranted for this use case.IOException
shouldn't be thrown by the CRT engine. If it is, then something is wrong that we likely don't understand and retrying may not be the best course of action.IOException
s may occur during local IO errors such as streaming from a file, reading system properties, string encoding problems, etc. It seemed wise to scope theseIOException
retries to just the HTTP call itself.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have an expect/actual for it FYI: https://github.com/awslabs/smithy-kotlin/blob/main/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt#L8
It entirely depends on how we wrap the exceptions. To your point though CRT JVM bindings throw generic exceptions with a CRT specific error code IIRC. I wasn't thinking of CRT though I was thinking of other JVM specific bindings that customers may writer or that we may provide in the future. Doing it at the retry policy level would capture all of them.
I think we are wrapping all of our HTTP related exceptions into an HttpException with an error code if we can map it. I suppose because of this handling it at the specific engine level makes sense. We just have to remember to do it for each engine.
suggestion : If we are handling this at the specific engine level I think we ought to probably make the CRT exceptions retryable as well if we can in this PR. It would require looking at specific error codes probably.