【问题标题】:Ruby Exceptions in a loop循环中的 Ruby 异常
【发布时间】:2012-03-10 19:52:39
【问题描述】:

我有一个 ruby​​ 脚本,它遍历一个缩短的 url 列表(一次大约 2,000 - 3,000 个)。目前一切都很顺利,直到点击格式错误、超时等的 url。当发生错误时,我的脚本会死掉。当/如果发生此类错误时,如何设置循环以跳到下一条记录。

我的循环如下所示:

blah.foo do |barurl|
  mymethod(barurl)

我的方法如下所示:

def mymethod(barurl)
  begin
    stuff
    ...
    return expandedurl
  rescue
    return "Problem expanding link"
  end
end

我的开始/结束逻辑是否应该围绕我的循环而不是方法?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    因为需要跳过格式错误的url,所以应该使用异常信息来控制循环

    blah.foo do |barurl|
      begin
        mymethod(barurl)
      rescue YourTypeOfException
        next
      end
    end
    

    在方法内部引发异常

    def mymethod(barurl)
      stuff
      ...
      raise YourTypeOfException, "this url is not valid"
      ...
    end
    

    【讨论】:

      【解决方案2】:

      是的。您的方法所做的只是处理异常并返回 another 任意对象以指示错误。

      您的方法不应处理其自身的异常情况。对调用者的反应做出假设是不礼貌的。

      blah.foo do |url|
        begin
          my_method url
        rescue
          next
        end
      end
      

      是否跳到下一个 URL 或打印消息不是该方法应该做出的决定。它唯一关心的应该是使用 URL。

      话虽如此,您应该简单地让它传播,并且只有在您可以实际处理它时才从它中解救出来。如果您能做的就是返回:timeout,请不要从TimeoutError 中解救。

      当您需要清理资源或只是让用户知道发生了错误时进行救援。

      此外,从每个可能的错误中拯救出来只是为了让它们消失是引入错误的好方法。尽可能具体。

      【讨论】:

      • 嗯 - 感谢 Matheus 的回答 - 但是......我认为你的回答与 Dave 和 keymone 不矛盾吗?也许我只是错过了一些东西。
      【解决方案3】:

      在你的方法中处理异常是正确的做法,所以你的实现很好

      我只能给你点红宝石语法糖:

      def some_method
        # here goes the code
      rescue Exception => e
        # here goes specific exception/error handling
      rescue
        # here goes error handling (not Exception handling though!)
      else
        # do this block when no exceptions are raised
      ensure
        # do this every time
      end
      

      顺便说一句,你不需要return 语句,代码块的最后一个值总是隐式返回

      啊,我想我在“如何跳过下一条记录”中误读了您的问题

      如果您想跳过当前不正确的记录之后,您必须从解析方法返回错误代码并使用breaknext 关键字在循环中设置跳过

      【讨论】:

        【解决方案4】:

        我发现现有的答案不令人满意,阅读 the documentation 向我表明,OP 的想法更像是那里建议的示例:

        [0, 1, 2].map do |i|
          10 / i
        rescue ZeroDivisionError
          nil
        end
        #=> [nil, 10, 5]
        

        文档特别指出,救援块允许循环在捕获的异常上继续(如示例所示)。

        【讨论】:

          【解决方案5】:

          它应该在循环内部,因此循环结构不会因异常而退出。但它看起来已经是——如果你在导致异常的方法内部进行救援,循环应该已经正常继续,因为它不应该看到异常。

          【讨论】:

          • 这就是我的想法,戴夫——但我的循环在看到异常时中断了。我可能需要回去看看我的异常处理。
          • @EdBloom 包括异常跟踪和足够的上下文来理解它将允许额外的帮助。假设它是一个 URL,你会根据返回值进行操作吗?
          猜你喜欢
          • 1970-01-01
          • 2011-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多