[英]ruby rescue block — respond with more than just one command
I'm running a script with an API that often times out. 我正在运行带有API的脚本,该脚本经常超时。 I'm using
begin/rescue
blocks to get it to redo
when this happens, but want to log what is happening to the command line before I run the redo
command. 当发生这种情况时,我正在使用
begin/rescue
块来redo
它,但是在运行redo
命令之前想要记录命令行中发生的事情。
begin
#...api query...
rescue ErrorClass
puts("retrying #{id}") && redo
end
Unfortunately the above script doesn't work. 不幸的是,上面的脚本不起作用。 Only the first command is run.
仅运行第一个命令。
I would like to force the rescue block to run multiple lines of code like so: 我想强制救援块运行多行代码,如下所示:
begin
# api query
rescue ErrorClass do ###or:# rescue ErrorClass do |e|
puts "retrying #{id}"
redo
end
but those don't work either. 但那些也不起作用。
I've had luck creating a separate method to run like so: 我有幸运行创建一个单独的方法来运行:
def example
id = 34314
begin
5/0
rescue ZeroDivisionError
eval(handle_zerodiv_error(id))
end
end
def handle_zerodiv_error(id)
puts "retrying #{id}"
"redo"
end
...that actually works. ......实际上有效。 But it requires too many lines of code in my opinion and it uses eval which is not kosher by any means according to my mentor(s).
但是在我看来,它需要太多的代码行,并且根据我的导师使用eval,这并不是犹太人。
You are unnecessarily complicating things by using &&
or do
. 使用
&&
或do
会使事情变得不必要。 The &&
version does not work because puts
returns nil
, so by shortcut evaluation of &&
, the part to follow is not evaluated. &&
版本不起作用,因为puts
返回nil
,因此通过&&
的快捷方式评估,不评估要遵循的部分。 If you use ||
如果你使用
||
or ;
或
;
instead, then it will work: 相反,它会工作:
begin
...
rescue ErrorClass
puts("retrying #{id}") || redo
end
begin
...
rescue ErrorClass
puts("retrying #{id}"); redo
end
but even this is not necessary. 但即使这样也没有必要。 You somehow seem to believe that you need a block within
rescue
to write multiple lines, but that does not make sense because you are not using a block with single line. 你似乎在某种程度上相信你需要一个
rescue
块来编写多行,但这没有意义,因为你没有使用单行的块。 There is no Ruby construction that requires a block only when you have multiple lines. 没有Ruby构造只有在有多行时才需要块。 So, just put them in multiple lines:
所以,只需将它们分成多行:
begin
...
rescue ErrorClass
puts("retrying #{id}")
redo
end
There is a retry
built in. This example is from "The Ruby Programming Language" pg 162. 内置了
retry
。这个例子来自“The Ruby Programming Language”第162页。
require "open-uri"
tries = 0
begin
tries +=1
open("http://www.example.com/"){|f| puts f.readlines}
rescue OpenURI::HTTPError => e
puts e.message
if (tries < 4)
sleep (2**tries) # wait for 2, 4 or 8 seconds
retry # and try again
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.