Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

S3.get_object with block for not-exist-key writes out error xml #207

Closed
takeru opened this issue Feb 9, 2015 · 6 comments
Closed

S3.get_object with block for not-exist-key writes out error xml #207

takeru opened this issue Feb 9, 2015 · 6 comments
Labels

Comments

@takeru
Copy link

takeru commented Feb 9, 2015

bucket = "valid-bucket"
key    = "not-exist-key"
filename = "./data.xxx"
File.unlink(filename) if File.exist?(filename)
File.open(filename,"wb") do |f|
  begin
    Aws::S3::Client.new.get_object(:bucket=>bucket, :key=>key) do |chunk|
      f.write(chunk)
    end
    puts "(no error)"
  rescue Object => e
    puts "e=#{e.inspect}"
  end
end
data = File.read(filename)
puts "data=[#{data}]"

exception raised:

#<NoMethodError: undefined method `rewind' for #<Seahorse::Client::BlockIO:0x007f88742b1548>>
ruby/2.1.0/gems/aws-sdk-core-2.0.22/lib/seahorse/client/http/response.rb:41:in `body_contents'

data.xxx includes error xml:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>not-exist-key</Key><RequestId>..........</RequestId><HostId>.............</HostId></Error>
@trevorrowe
Copy link
Contributor

Thanks for reporting this error and steps for reproduction. I've duplicated the error locally and I'll try to get a fix out with tomorrows release.

Generaly, I would not recomend using block form for reading. It has the downside that once bytes have been written to the block, the Ruby SDK is unable to retry failed requests. Might I recomend using the following form for get:

s3 = Aws::S3::Client.new
s3.get_object(bucket:'bucket-name, key:'key', response_target:'./path/to/file')

The fix involves updating the block form to not yield the response body when it is not a 200 response.

@trevorrowe
Copy link
Contributor

The block should only receive actual data now, and the method will raise the error normally now. Thanks for reporting the issue!

@takeru
Copy link
Author

takeru commented Feb 13, 2015

Thanks!

But I am using:

obj = Aws::S3::Resource.new.bucket(@bucket).object(@key)
obj.get(:response_target=>"local_file")

@sapientpants
Copy link

Should this be treating any 2xx response code as success? I'm thinking specifically 206 as I've noticed that requests with a range specified leave the response in the body property of the get_object return value and don't get written out to the response_target with the 2.0.24 release. This used to work with 2.0.22.

@trevorrowe
Copy link
Contributor

@marrrt Good catch. I've submitted a patch that expands this to handle 200..299 status codes.

@trevorrowe
Copy link
Contributor

See aws/aws-sdk-ruby@81a5121

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants