2014-02-08 36 views
1

我正在运行一个API,经常超时的脚本。我在使用begin/rescue块将其发送到redo,但是在运行redo命令之前,要记录命令行中发生的情况。红宝石救援块 - 回应不止一个命令

begin 
#...api query... 
rescue ErrorClass 
    puts("retrying #{id}") && redo 
end 

不幸的是,上面的脚本不起作用。只有第一个命令运行。

我想迫使救援块运行多行代码如下所示:

begin 
# api query 
rescue ErrorClass do ###or:# rescue ErrorClass do |e| 
    puts "retrying #{id}" 
    redo 
end 

但那些不工作的。

我有运气创建一个单独的方法来这样运行:

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 

...的实际工作。但是,在我看来,它需要太多的代码行,它使用根据我的导师的任何方式不是犹太教的eval。

+0

什么是你的代码redo'的'目的,我没有得到你在找什么 –

+0

大部分我能够在启动过程中的时间再次在那个给定的ID,错误发生在和它的作品。因此,我正试图在没有脚本中断的情况下做到这一点。不可避免地会出现一些API命令本身导致错误的情况,所以我想知道脚本何时卡在相同的ID上。 –

+0

*我想强制救援块运行多行代码* - 问题是什么?你的意思是最后一行没有执行? –

回答

2

您可以利用&&do不必要地复杂的事情。 &&版本不起作用,因为puts返回nil,因此通过快捷方式评估&&,不会评估要遵循的部分。如果您使用||;代替,那么它会工作:

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}") || redo 
end 

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}"); redo 
end 

但即使这样是没有必要的。你似乎相信你需要在rescue之内的一个块来写多行,但这没有意义,因为你没有使用单行的块。没有Ruby结构只有当你有多行时才需要一个块。所以,只要把他们在多行:

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}") 
    redo 
end 
1

有建于retry这个例子是从“Ruby编程语言”第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 
+0

我想'retry'会再次尝试整个'Enumerable'组('array'),'redo'只会重试给定的'Enumberable'成员('array [n]') –