我有一个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
我的开始/结束逻辑是否应该绕着我的循环而不是方法?
答案 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]
文档特别指出,救援块允许循环在捕获的异常上继续执行(如示例所示)。