Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionDispatch::Http::UploadedFile#read returns empty string

I have a Rails app where I'm parsing an uploaded CSV. I just discovered that the parsing has stopped working and am investigating.

I've tracked it back to the fact that I call .read on an instance of ActionDispatch::Http::UploadedFile, and that returns an empty string.

The uploaded file is not empty, and when I inspect the UploadedFile object, it has an attribute like @tempfile=#<File:/tmp/RackMultipart20130530-34976-6jaqt5. If I cat that file on the filesystem, it contains what I expect.

Why might .read return an empty string?

I'm using Rails 3.2.13.

like image 233
Nathan Long Avatar asked May 30 '13 15:05

Nathan Long


1 Answers

Try rewinding

My colleague suggested calling rewind before read, and that works. Apparently some other code is reading the file first.

Update

Nobody's reading the file before I am, as far as I can tell. I created an initializer to spy on the UploadedFile:

# config/initializers/uploaded_file.rb
class ActionDispatch::Http::UploadedFile

  alias_method :old_read, :read
  def read(*args)
    Rails.logger.info "file #{self} is getting read by #{caller.first}!"
    old_read(*args)
  end
end

I didn't see any other calls to read. Thinking there might be some other method called that would advance the read pointer, I went further and replaced the class entirely:

# config/initializers/uploaded_file.rb
ActionDispatch::Http::UploadedFile = Class.new do

  def initialize(*args)
    Rails.logger.info "initilized with #{args}"
  end

  def method_missing(method_name, *args, &block)
    Rails.logger.info "file got #{method_name} with #{args}.\
      Block? #{block_given?} caller? #{caller.first}"
  end

end

Still nothing. I see a call to initialize, my call to rewind, and my call to read.

Seems like this file comes pre-wound to the end. I'm not sure why that might be, but rewind is still the fix for me.

like image 50
Nathan Long Avatar answered Nov 15 '22 03:11

Nathan Long