【问题标题】:How do I rescue a Capybara Error Twice?如何两次拯救 Capybara 错误?
【发布时间】:2015-06-13 15:02:54
【问题描述】:

我正在使用 Capybara 检查页面中的元素并返回其内容。如果元素不存在,我想查找不同元素的内容并返回。如果两者都没有找到,我想返回一个空字符串。

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

对于选择“返回元素或空字符串”的情况,这很简单——我只需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 ....

【问题讨论】:

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


    【解决方案1】:

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

    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
    

    【讨论】:

      【解决方案2】:

      为什么不试试这个,嵌套异常从我所做的工作。这应该可以工作,并且第二次引发异常时,您可以肯定地说您正在做的事情确实被破坏了。

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

      【讨论】:

        【解决方案3】:

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

        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
        

        【讨论】:

        • 在这种情况下,您可以直接使用救援而不用开始。 :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-22
        • 2016-06-21
        • 2013-11-27
        • 1970-01-01
        • 1970-01-01
        • 2020-12-15
        相关资源
        最近更新 更多