Rescue won't rescue in Rails
I'm writing a simple app that proces开发者_JS百科ses POST
ed CSV files and am testing it against invalid input (e.g. non-CSV files). I'm using the CSV::Reader.parse command to parse the CSV in a controller method, as follows:
@parsed_file = CSV::Reader.parse(params[:file]) rescue []
However, despite the rescue statement, I'm still getting an uncaught CSV::IllegalFormatError
when improper submissions are entered. What am I missing here?
Thanks!
You need to pass a file handle to parse:
@parsed_file = CSV::Reader.parse(File.open(params[:file], 'rb')) rescue []
I ended up having to monkey-patch the CSV::Reader class to properly handle the exception. I'm still not sure why it wasn't being caught in the controller, but here's the code I ended up writing:
class CSV
class Reader
def each
while true
row = []
parsed_cells = get_row(row) rescue 0
if parsed_cells == 0
break
end
yield(row)
end
nil
end
end
end
Note the rescue 0
after the call to get_row
, which isn't present in the original. Definitely an ugly hack, but it'll serve my purposes.
If anyone can explain why the exception wasn't being caught in the controller, I'll gladly give them points for having the correct answer.
It sounds as if your CSV::IllegalFormatError
isn't properly subclassing RuntimeError
. Or alternatively RuntimeError
has been changed to not subclass StandardError
.
Only Errors which subclass StandardError
are caught by default rescue blocks. To test this theory try
@parsed_file = begin
CSV::Reader.parse(params[:file])
rescue StandardError
puts "I caught a StandardError"
[]
rescue Exception => e
puts "I caught #{e.class}->#{e.class.superclass}->#{e.class.superclass.superclass}"
[]
end
This would explain why I (and probably others) can't repeat this problem.
Whatever the case using Exception
explicitly should work, and will be cleaner than a monkey patch.
精彩评论