Skip to content

Commit

Permalink
Simple attributes support for conditional check errors (#2917)
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp authored Sep 26, 2023
1 parent 795abfd commit f4a09d8
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 10 deletions.
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

0 comments on commit f4a09d8

Please sign in to comment.