Skip to content

Commit

Permalink
Handle S3 200 errors for all operations #2 (#3040)
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp authored Jun 7, 2024
1 parent 6d9d5eb commit 8ed1bb9
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 96 deletions.
2 changes: 2 additions & 0 deletions gems/aws-sdk-s3/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Issue - Handle 200 errors for all S3 operations that do not have streaming responses.

1.152.0 (2024-06-05)
------------------

Expand Down
43 changes: 27 additions & 16 deletions gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/http_200_errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,40 @@ class Handler < Seahorse::Client::Handler

def call(context)
@handler.call(context).on(200) do |response|
if error = check_for_error(context)
context.http_response.status_code = 500
response.data = nil
response.error = error
end
return response if streaming_output?(context.operation.output)

error = check_for_error(context)
return response unless error

context.http_response.status_code = 500
response.data = nil
response.error = error
end
end

private

def streaming_output?(output)
if (payload = output[:payload_member]) # checking ref and shape
payload['streaming'] || payload.shape['streaming'] ||
payload.eventstream
else
false
end
end

def members_in_body?(output)
output.shape.members.any? { |_, k| k.location.nil? }
end

def check_for_error(context)
xml = context.http_response.body_contents
if xml.match(/<Error>/)
if xml.match(/\?>\s*<Error>/)
error_code = xml.match(/<Code>(.+?)<\/Code>/)[1]
error_message = xml.match(/<Message>(.+?)<\/Message>/)[1]
S3::Errors.error_class(error_code).new(context, error_message)
elsif !xml.match(/<\w/) # Must have the start of an XML Tag
elsif members_in_body?(context.operation.output) && !xml.match(/<\w/)
# Must have a body member and have the start of an XML Tag
# Other incomplete xml bodies will result in XML ParsingError
Seahorse::Client::NetworkingError.new(
S3::Errors
Expand All @@ -40,15 +59,7 @@ def check_for_error(context)
end
end

handler(
Handler,
step: :sign,
operations: [
:complete_multipart_upload,
:copy_object,
:upload_part_copy,
]
)
handler(Handler, step: :sign)
end
end
end
Expand Down
168 changes: 88 additions & 80 deletions gems/aws-sdk-s3/spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,16 @@ module S3
'rw0nS41rawnLDzkf+PKXmmt/uEi4bzvNMr72o=',
'x-amz-request-id' => 'BE9C18E622969B17'
},
body: ''
)
body: <<-XML)
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">
<Buckets>
<Bucket>
<Name>aws-sdk-ruby</Name>
</Bucket>
</Buckets>
</ListAllMyBucketsResult>
XML
Seahorse::Client::Response.new(context: context)
end
resp = s3.list_buckets
Expand Down Expand Up @@ -423,14 +431,14 @@ module S3
status_code: 409,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BucketNotEmpty</Code>
<Message>The bucket you tried to delete is not empty</Message>
<BucketName>aws-sdk</BucketName>
<RequestId>740BE6AB575EACED</RequestId>
<HostId>MQVg1RMI+d93Hps1E8qpIuDb9Gd2TzkDhm0wE40981DjxSHP1UfLBB7qOAlwAqJB</HostId>
</Error>
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BucketNotEmpty</Code>
<Message>The bucket you tried to delete is not empty</Message>
<BucketName>aws-sdk</BucketName>
<RequestId>740BE6AB575EACED</RequestId>
<HostId>MQVg1RMI+d93Hps1E8qpIuDb9Gd2TzkDhm0wE40981DjxSHP1UfLBB7qOAlwAqJB</HostId>
</Error>
XML
)
Seahorse::Client::Response.new(context: context)
Expand All @@ -452,8 +460,8 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
XML
)
Seahorse::Client::Response.new(context: context)
Expand All @@ -469,8 +477,8 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
XML
)
Seahorse::Client::Response.new(context: context)
Expand Down Expand Up @@ -504,19 +512,19 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<Marker>c%26</Marker>
<NextMarker>d%26</NextMarker>
<Contents>
<Key>e%26</Key>
</Contents>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListBucketResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<Marker>c%26</Marker>
<NextMarker>d%26</NextMarker>
<Contents>
<Key>e%26</Key>
</Contents>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -541,12 +549,12 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>a%26</Key>
</Contents>
</ListBucketResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>a%26</Key>
</Contents>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -562,22 +570,22 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Version>
<Key>e%26</Key>
</Version>
<DeleteMarker>
<Key>f%26</Key>
</DeleteMarker>
<CommonPrefixes>
<Prefix>g%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Version>
<Key>e%26</Key>
</Version>
<DeleteMarker>
<Key>f%26</Key>
</DeleteMarker>
<CommonPrefixes>
<Prefix>g%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -602,19 +610,19 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Upload>
<Key>e%26</Key>
</Upload>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Upload>
<Key>e%26</Key>
</Upload>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand Down Expand Up @@ -686,17 +694,17 @@ module S3
status_code: 200,
headers: {},
body: <<-XML)
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>prefix+suffix</Key>
</Contents>
<Contents>
<Key>prefix%2Bsuffix</Key>
</Contents>
<Contents>
<Key>prefix%20suffix</Key>
</Contents>
</ListBucketResult>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>prefix+suffix</Key>
</Contents>
<Contents>
<Key>prefix%2Bsuffix</Key>
</Contents>
<Contents>
<Key>prefix%20suffix</Key>
</Contents>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand Down Expand Up @@ -781,13 +789,13 @@ module S3
client.handle(step: :send) do |context|
context.http_response.signal_headers(200, {})
context.http_response.signal_data(<<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InternalError</Code>
<Message>We encountered an internal error. Please try again.</Message>
<RequestId>656c76696e6727732072657175657374</RequestId>
<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>
</Error>
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InternalError</Code>
<Message>We encountered an internal error. Please try again.</Message>
<RequestId>656c76696e6727732072657175657374</RequestId>
<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>
</Error>
XML
context.http_response.signal_done
Seahorse::Client::Response.new(context: context)
Expand Down

0 comments on commit 8ed1bb9

Please sign in to comment.