在救援声明中包装每个命令

时间:2012-10-23 11:54:42

标签: ruby selenium exception-handling

我有10个Ruby函数调用我想执行,每次调用都可能抛出异常。我想以同样的方式处理每个异常并继续。有没有办法在begin ... rescue ... end块中包裹每一行?

[编辑]:用例是一个屏幕抓取器/自动化工具,它使用Selenium Web驱动程序填写表单。我不想打扰检查select元素中的选项是否存在,只是尽可能地填写它们。为此,我需要调用Selenium::WebDriver::Support::Select.select_by并继续,如果它抛出“无法找到值为x的选项”异常。

5 个答案:

答案 0 :(得分:6)

我发现this answer也符合我的要求:

def action
    yield
    rescue
        ....
    ensure
        ....
end

action { call1 }
action { call2 }
action { call3 }

答案 1 :(得分:5)

你的意思是这样的吗?

class Wtf
  def f1
    raise "f1"
  end
  def f2
    raise "f2"
  end
end

obj= Wtf.new

[:f1, :f2].each do |f|
  begin
    obj.send f
  rescue Exception=> e
    p e
  end
end

编辑:为示例添加了更多代码

答案 2 :(得分:2)

我喜欢使用#send的qwned方法,但是对于并非所有方法都会按顺序调用的情况,它并不理想。

Continuations非常适合这类事情:

require 'continuation'

class Continuer

  # Define five methods for testing
  (1..5).each { |i| define_method("method#{i}") { puts "method#{i} called" } }

  def do_these_things
    cc = nil
    callcc { |c| cc = c; method1; }
    callcc { |c| cc = c; method2; raise }
    # Do other things right here, maybe...
    callcc { |c| cc = c; method3; raise }
    callcc { |c| cc = c; method4; }
    callcc { |c| cc = c; method5; }
  rescue
    puts 'Caught exception.  Continuing.'
    cc.call
  end

end

Continuer.new.do_these_things

这可以通过在执行每个容易出错的方法时在'cc'变量中记录延续来实现。然后救援声明只是在那个延续时间恢复。它有点像带有动态标签的goto语句。

答案 3 :(得分:0)

你可以这样做:

begin
  do_something
  do_something_else
  do_do_do
rescue Exception1 => e
  # error handling
rescue Exception2 => e
  # error handling

如果do_something抛出异常,则不会调用其他调用。我认为比做begin.. rescue块很多更好。只需处理不同的例外情况。

答案 4 :(得分:0)

def f1; raise "X"; end
def f2; raise "Y"; end
#...
funcList = [:f1,:f2,...]
funcList.each{|f|
     begin
       send(f)
     rescue Exception => e
        #handle
     end
 }