如何救出Capybara Error Twice?

时间:2015-04-08 14:59:40

标签: ruby-on-rails ruby exception error-handling capybara

我使用Capybara检查某个元素的页面并返回它的内容。如果该元素不存在,我希望查找不同元素的内容并返回该内容。如果两者都找不到,我想要返回一个空字符串。

这里的挑战是当Capybara::ElementNotFound失败时,Capybara会抛出#find错误。

用于选择何时为"返回元素或空字符串"这很简单 - 我只需rescue并返回空字符串,如下所示:

def select_post_meta_name(page)
  selector = 'div.post-name'
  page.find(selector).text
rescue Capybara::ElementNotFound => e
  Rails.logger.warn('Could not get meta name: ' + e)
  ''
end

我如何重构上面的代码来处理类似下面伪代码的意图?

# FAKE EMBARRASSING PSEUDO CODE ....
def select_post_meta_name(page)
  selector = 'div.post-name'
  page.find(selector).text
rescue Capybara::ElementNotFound => e
  other_element_selector = 'div.post-title'
  page.find(other_element_selector).text

  rescue Capybara::ElementNotFound => e
    Rails.logger.warn('Could not find any elements: ' + e)
    ''
end
# /FAKE EMBARRASSING PSEUDO CODE ....

3 个答案:

答案 0 :(得分:2)

您可以在救援区中使用重试或“递归”再次使用参数调用该方法。

def select_post_meta_name(page, meta_name = 'div.post-name')
  re_try = false
  begin
    page.find(meta_name).text
  rescue Capybara::ElementNotFound => e
    if re_try
      Rails.logger.warn('Could not find any elements: ' + e)
    else
      meta_name = 'div.post-title'
      re_try = true
      retry
    end
  end
end

答案 1 :(得分:1)

您可以使用一个标志再次调用该方法,表示您正在第二次执行该方法:

def select_post_meta_name(page, selector = 'div.post-name', first_call_of_method = true)
  begin
    page.find(selector).text
  rescue Capybara::ElementNotFound => e
    if first_call_of_method
      select_post_meta_name(page, 'div.post-title', false)
    else
      Rails.logger.warn('Could not find any elements: ' + e)
    end
  end
end

答案 2 :(得分:1)

为什么不试试这个,嵌套异常与我所做的一致。这应该可以工作,第二次抛出异常然后你可以肯定地说你正在做的事情真的坏了。

# FAKE EMBARRASSING PSEUDO CODE ....
def select_post_meta_name(page)
  selector = 'div.post-name'
  begin
    page.find(selector).text
  rescue Capybara::ElementNotFound => e
    begin
      other_element_selector = 'div.post-title'
      page.find(other_element_selector).text
    rescue Capybara::ElementNotFound => e
      Rails.logger.warn('Could not find any elements: ' + e)
      ''
    end
  end
end
# /FAKE EMBARRASSING PSEUDO CODE ....