循环中的Ruby异常

时间:2012-03-10 19:52:40

标签: ruby

我有一个ruby脚本循环显示一个缩短的网址列表(一次大约2,000 - 3,000)。目前一切都是桃子,直到击中一个格式错误的网址,超时等。当一个错误发生时,我的脚本就会死亡。如果发生此类错误,如何设置循环以跳至下一条记录。

我的循环看起来像这样:

blah.foo do |barurl|
  mymethod(barurl)

我的mymethod看起来像这样:

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

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

5 个答案:

答案 0 :(得分:10)

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

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

并在方法内部引发异常

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

答案 1 :(得分:1)

是。您的所有方法都是使用异常并返回另一个任意对象以指示错误。

您的方法不应该处理自己的特殊情况。对于调用者将如何反应做出假设是非常粗鲁的。

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

是否跳转到下一个URL或打印消息不是该方法应该做出的决定。唯一需要考虑的是使用URL。

话虽如此,你应该简单地让它传播,只有当你真正处理它时才能从中拯救它。如果你所能做的只是返回TimeoutError,请不要从:timeout救出。

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

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

答案 2 :(得分:1)

它应该在里面循环,所以循环结构不会在异常中退出。但看起来它已经是 - 如果你在导致异常的方法内部进行抢救,循环应该已经正常继续,因为它不应该看到异常。

答案 3 :(得分:1)

在您的方法中进行异常处理是正确的方法,因此您的实现很好

我只能指出一些红宝石sytax糖:

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语句,代码块的最后一个值总是隐式返回

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

如果你想在当前错误之后跳过记录,那么你必须从你的解析方法中返回错误代码,并使用break或{{在你的循环中设置跳过1}}关键字

答案 4 :(得分:0)

我发现现有的答案不令人满意,阅读the documentation对我来说,OP的想法更像是建议的例子:

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

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