将每个命令包含在救援语句中

问题描述 投票:0回答:6

我想要执行 10 个 Ruby 函数调用,每个调用都可能抛出异常。我想以相同的方式处理每个异常并继续。有没有办法做到这一点,而不将每一行包装在

begin
...
rescue
...
end
块中?

[编辑]:此用例是一个屏幕抓取/自动化工具,它使用 Selenium Web 驱动程序来填写表单。我不想费心检查选择元素中的选项是否存在,只需尽可能地填写它们即可。为此,我需要调用

Selenium::WebDriver::Support::Select.select_by
并在抛出“无法找到值为 x 的选项”异常时继续。

ruby selenium exception
6个回答
7
投票

我找到了这个答案,它也能满足我的要求:

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

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

6
投票

你的意思是这样的吗?

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
投票

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

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 语句。


0
投票

你可以这样做:

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

如果 do_something 抛出异常,则其他调用将不会被调用。我认为这比做很多

begin.. rescue
块更好。只需处理不同的异常即可。


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
 }

0
投票

Ruby 2.5开始,引入了功能#12906,我们可以在

each
块中进行救援,而无需
begin

(1..3).each do |i|
  send(:"method_#{i}")
rescue => e
  puts e.message
end

# output
undefined method `method_1' for main:Object
undefined method `method_2' for main:Object
undefined method `method_3' for main:Object

© www.soinside.com 2019 - 2024. All rights reserved.