Non-tech founder’s guide to choosing the right software development partner Download Ebook
Home>Blog>Rewind files before reading

Rewind Files Before Reading

Suppose you have a form with a file input and you need to forward that file to an external service through your Rails app. Params will look like this:


{ "file"=> #<ActionDispatch::Http::UploadedFile:0x00007fce9a8af140 @tempfile=#<Tempfile:/path/to/the/file.xlsx>, ... > }

The external service can not be reached for the first time sometimes, so you decided to set some retry count.


retry_count = 5

while retry_count > 0

    begin

        HTTPClient.new.post(url, params, headers)

    rescue ExternalServiceUnavailable => e

        retry_count -= 1

    end

end

The code above uses HTTPClient gem for making http requests and it will raise the following error in case there will be at least one retry:

ArgumentError: Illegal size value: #size returns 154139 but cannot read

The thing is that HTTPClient uses IO#read to read the file by chunks for making POST request. The lineno pointer reaches the end of the file after read, and you can not read bytes from the I/O stream anymore:


params['file'].tempfile.eof? # => true

To fix that, use IO#rewind – it positions IO to the beginning of input, resetting lineno to zero. Just add checking the file for eof before each request and rewind it if needed:


retry_count = 5

while retry_count > 0

    begin

        params['file'].tempfile.rewind if params['file'].tempfile.eof? # check eof

        HTTPClient.new.post(url, params, headers)

    rescue ExternalServiceUnavailable => e

        retry_count -= 1

    end

end

Categories:

Recent Projects

We take pride in creating applications that drive growth and evolution, from niche startups to international companies.

Let’s Build Something Great Together

Let’s discuss your project and see how Ruby on Rails can be your competitive advantage.

*By submitting this form, you agree with JetRockets’ Privacy Policy