我正在编写一个简单的应用程序,用于处理POST
ed CSV文件,并针对无效输入(例如非CSV文件(进行测试。我使用CSV::Reader.parse命令来解析控制器方法中的CSV,如下所示:
@parsed_file = CSV::Reader.parse(params[:file]) rescue []
然而,尽管有救援声明,当输入不正确的提交时,我仍然得到一个未捕获的CSV::IllegalFormatError
。我在这里错过了什么?
谢谢!
您需要传递一个文件句柄来解析:
@parsed_file = CSV::Reader.parse(File.open(params[:file], 'rb')) rescue []
我最终不得不对CSV::Reader类进行猴子补丁以正确处理异常。我仍然不确定为什么它没有被控制器捕获,但这是我最终写的代码:
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
注意调用get_row
之后的rescue 0
,它在原始文件中不存在。这绝对是一次丑陋的黑客攻击,但它会达到我的目的。
如果有人能解释为什么控制器中没有捕捉到异常,我很乐意为他们的正确答案打分。
听起来好像您的CSV::IllegalFormatError
没有正确地将RuntimeError
子类化。或者可替换地,RuntimeError
已被改变为不是StandardError
的子类。
只有StandardError
子类的错误才会被默认的救援块捕获。要测试这个理论,请尝试
@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
这可以解释为什么我(可能还有其他人(不能重复这个问题。
无论在什么情况下,明确使用Exception
都应该有效,而且比猴子补丁更干净。