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

Simple attributes support for conditional check errors #2917

Merged
merged 6 commits into from
Sep 26, 2023
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
2 changes: 1 addition & 1 deletion build_tools/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ServiceEnumerator
MANIFEST_PATH = File.expand_path('../../services.json', __FILE__)

# Minimum `aws-sdk-core` version for new gem builds
MINIMUM_CORE_VERSION = "3.177.0"
MINIMUM_CORE_VERSION = "3.184.0"

# Minimum `aws-sdk-core` version for new S3 gem builds
MINIMUM_CORE_VERSION_S3 = "3.181.0"
Expand Down
2 changes: 2 additions & 0 deletions gems/aws-sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Change the `ServiceError` data member from read only to read/write.

3.183.1 (2023-09-25)
------------------

Expand Down
2 changes: 1 addition & 1 deletion gems/aws-sdk-core/lib/aws-sdk-core/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def initialize(context, message, data = Aws::EmptyStructure.new)
attr_reader :context

# @return [Aws::Structure]
attr_reader :data
attr_accessor :data

class << self

Expand Down
2 changes: 2 additions & 0 deletions gems/aws-sdk-dynamodb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Simple attributes conversion for item data returned in `ConditionalCheckFailedException` and other exceptions. (Breaking change / bug fix)

1.94.0 (2023-09-26)
------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ module Plugins
# # note that the request `:key` had to be type prefixed
# resp = dynamodb.get(table_name: 'aws-sdk', key: { 'id' => { s: 'uuid' }})
# resp.item
# # {
# # "id"=> <struct s='uuid', n=nil, b=nil, ss=nil, ns=nil, bs=nil, m=nil, l=nil, null=nil, bool=nil>
# # "age"=> <struct s=nil, n="35", b=nil, ss=nil, ns=nil, bs=nil, m=nil, l=nil, null=nil, bool=nil>
# # ...
# # }
# {
# "id"=> <struct s='uuid', n=nil, b=nil, ss=nil, ns=nil, bs=nil, m=nil, l=nil, null=nil, bool=nil>
# "age"=> <struct s=nil, n="35", b=nil, ss=nil, ns=nil, bs=nil, m=nil, l=nil, null=nil, bool=nil>
# ...
# }
#
class SimpleAttributes < Seahorse::Client::Plugin

Expand Down Expand Up @@ -119,26 +119,40 @@ def call(context)
@handler.call(context).on(200) do |response|
response.data = translate_output(response)
end
rescue Aws::Errors::ServiceError => e
e.data = translate_error_data(context, e.data)
raise e
end

private

def translate_input(context)
if shape = context.operation.input
if (shape = context.operation.input)
ValueTranslator.new(shape, :marshal).apply(context.params)
else
context.params
end
end

def translate_output(response)
if shape = response.context.operation.output
if (shape = response.context.operation.output)
ValueTranslator.new(shape, :unmarshal).apply(response.data)
else
response.data
end
end

def translate_error_data(context, error_data)
shape = context.operation.errors.find do |e|
error_data.is_a?(e.shape.struct_class)
end
if shape
ValueTranslator.new(shape, :unmarshal).apply(error_data)
else
error_data
end
end

end

# @api private
Expand Down
24 changes: 23 additions & 1 deletion gems/aws-sdk-dynamodb/spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ module DynamoDB
expect(resp.data.item).to eq('id' => 'guid')
end

it 'unmarshals attribute values in errors' do
ddb.handle(step: :send) do |context|
context.http_response.signal_headers(400, {})
context.http_response.signal_data(<<-JSON)
{
"__type": "com.amazonaws.dynamodb.v20120810#ConditionalCheckFailedException",
"Message": "The conditional request failed.",
"Item": { "id": { "S": "guid" } }
}
JSON
context.http_response.signal_done
Seahorse::Client::Response.new(context: context)
end
expectation = proc do |error|
expect(error).to be_a(Errors::ConditionalCheckFailedException)
expect(error.data.item).to eq('id' => 'guid')
end
expect do
ddb.put_item(table_name: 'aws-sdk', item: { 'id' => 'guid' })
end.to raise_error(&expectation)
end

it 'avoids double-marshaling of structs' do
batch = {
"TableName" => [
Expand Down Expand Up @@ -213,7 +235,7 @@ module DynamoDB
context.http_response.signal_data(<<-JSON)
{
"__type": "com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
"message": "Requested resource not found: Table: abc not found"
"Message": "Requested resource not found: Table: abc not found"
}
JSON
context.http_response.signal_done
Expand Down
Loading