简体   繁体   English

救援不会在 Rails 中救援

[英]Rescue won't rescue in Rails

I'm writing a simple app that processes POST ed CSV files and am testing it against invalid input (eg non-CSV files).我正在编写一个简单的应用程序来处理POST ed CSV 文件,并针对无效输入(例如非 CSV 文件)对其进行测试。 I'm using the CSV::Reader.parse command to parse the CSV in a controller method, as follows:我正在使用 CSV::Reader.parse 命令在 controller 方法中解析 CSV,如下所示:

@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.但是,尽管有救援声明,当输入不正确的提交时,我仍然会收到未捕获的CSV::IllegalFormatError 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.我最终不得不对 CSV::Reader class 进行猴子补丁以正确处理异常。 I'm still not sure why it wasn't being caught in the controller, but here's the code I ended up writing:我仍然不确定为什么它没有被 controller 捕获,但这是我最终编写的代码:

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.请注意调用get_row之后的rescue 0 ,这在原始文件中不存在。 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.如果有人能解释为什么在 controller 中没有捕获到异常,我很乐意为他们提供正确答案的分数。

It sounds as if your CSV::IllegalFormatError isn't properly subclassing RuntimeError .听起来好像您的CSV::IllegalFormatError没有正确继承RuntimeError Or alternatively RuntimeError has been changed to not subclass StandardError .或者RuntimeError已更改为不是StandardError的子类。

Only Errors which subclass StandardError are caught by default rescue blocks.默认救援块仅捕获子类StandardError的错误。 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.无论在何种情况下明确使用Exception都应该有效,并且比猴子补丁更干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM