Skip to content
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 S3 200 Error handling #3288

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/next-release/bugfix-s3-1405.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "bugfix",
"category": "``s3``",
"description": "Fix S3 200 Error handling to address bugs introduced in payload operations."
}
22 changes: 17 additions & 5 deletions botocore/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1245,11 +1245,7 @@ def document_expires_shape(section, event_name, **kwargs):
def _handle_200_error(operation_model, response_dict, **kwargs):
# S3 can return a 200 response with an error embedded in the body.
# Convert the 200 to a 500 for retry resolution in ``_update_status_code``.
if (
not response_dict
or operation_model.has_streaming_output
or operation_model.has_event_stream_output
):
if not _should_handle_200_error(operation_model, response_dict):
# Operations with streaming response blobs are excluded as they
# can't be reliably distinguished from an S3 error.
return
Expand All @@ -1262,6 +1258,22 @@ def _handle_200_error(operation_model, response_dict, **kwargs):
)


def _should_handle_200_error(operation_model, response_dict):
output_shape = operation_model.output_shape
if (
not response_dict
or operation_model.has_event_stream_output
or not output_shape
):
return False
payload = output_shape.serialization.get('payload')
if payload is not None:
payload_shape = output_shape.members[payload]
if payload_shape.type_name in ('blob', 'string'):
return False
return True


def _update_status_code(response, **kwargs):
# Update the http_response status code when the parsed response has been
# modified in a handler. This enables retries for cases like ``_handle_200_error``.
Expand Down
Loading