Rails 中的救援不会救援

发布于 2024-11-18 06:18:47 字数 310 浏览 2 评论 0原文

我正在编写一个简单的应用程序,用于处理 POSTed CSV 文件,并针对无效输入(例如非 CSV 文件)对其进行测试。我正在使用 CSV::Reader.parse 命令在控制器方法中解析 CSV,如下所示:

@parsed_file = CSV::Reader.parse(params[:file]) rescue []

但是,尽管有救援语句,我仍然收到未捕获的 CSV::IllegalFormatError :输入了不正确的提交内容。我在这里缺少什么?

谢谢!

I'm writing a simple app that processes POSTed 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心碎无痕… 2024-11-25 06:18:47

您需要传递一个文件句柄来解析:

@parsed_file = CSV::Reader.parse(File.open(params[:file], 'rb')) rescue []

You need to pass a file handle to parse:

@parsed_file = CSV::Reader.parse(File.open(params[:file], 'rb')) rescue []
甜柠檬 2024-11-25 06:18:47

我最终不得不对 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,原著中不存在这一点。绝对是一个丑陋的黑客,但它会达到我的目的。

如果有人能解释为什么控制器没有捕获异常,我很乐意为他们提供正确的答案。

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.

南…巷孤猫 2024-11-25 06:18:47

听起来好像您的 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 都应该有效,并且比猴子补丁更干净。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文