如何拯救 Capybara Error Twice?

How do I rescue a Capybara Error Twice?

我正在使用 Capybara 检查页面中的元素和 return 它的内容。如果该元素不存在,我想查找其他元素的内容并 return 那个。如果两者都找不到,我想 return 一个空字符串。

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

当大小写为 "return the element or an empty string" 时,这很简单——我只需 rescue 和 return 空字符串,如下所示:

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 ....

您可以再次调用该方法,并带有一个标志,表明您正在第二次执行该方法:

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

您可以在救援块中使用重试或"recursive"使用参数再次调用该方法。

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

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

# 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 ....