我经常发现自己在处理这样的场景:
require 'nokogiri'
require "open-uri"
url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))
# Let's say one of the following line breaks the ruby script
# because the element I'm searching doesn't contain an attribute.
a = nokodoc.search('#element-1').attribute('href').text
b = nokodoc.search('#element-2').attribute('href').text.gsub("a", "A")
c = nokodoc.search('#element-3 h1').attribute('style').text.strip发生的情况是,我将创建大约30个变量,所有变量都在一个页面中搜索不同的元素,并且我将在多个页面上循环该代码。但是,其中一些页面的布局可能会略有不同,并且不会有这样的div。这会破坏我的代码(例如,您不能在nil上调用.attribute或.gsub )。但是我从来不能事先猜到哪一行。我的首选解决方案通常是在每行后面加上:
begin
line #n
rescue
puts "line #n caused an error"
end我希望能够做一些如下的事情:
url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))
catch_error(a, nokodoc.search('#element-1').attribute('href').text)
catch_error(b, nokodoc.search('#element-2').attribute('href').text.gsub("a", "A"))
catch_error(c, nokodoc.search('#element-3 h1').attribute('style').text.strip)
def catch_error(variable_name, code)
begin
variable_name = code
rescue
puts "Code in #{variable_name} caused an error"
end
variable_name
end我知道在每个新方法工作之前放入&:
nokodoc.search('#element-1')&.attribute('href')&.text但我希望能够在我的终端中使用'puts‘来显示错误,以查看我的代码何时给出错误。
有可能吗?
发布于 2016-11-15 09:42:13
您不能将code作为常规参数传递给方法,因为它在传递给catch_error方法之前会被计算(并引发异常)。你可以把它作为一个块来传递--类似于
a = catch_error('element_1 href text') do
nokodoc.search('#element-1').attribute('href').text
end
def catch_error(error_description)
yield
rescue
puts "#{error_description} caused an error"
end注意,您不能将a作为variable_name传递给该方法:在调用该方法之前,没有在任何地方定义它,因此您将得到一个undefined local variable or method错误。即使你早点定义了a,它也不能正常工作。如果您的代码工作时没有引发异常,则该方法将返回正确的值,但该值不会存储在该方法作用域之外的任何地方。如果出现异常,variable_name将具有a在该方法之前具有的值(如果您在未设置的情况下定义了它,则为nil),因此您的错误消息将输出类似Code in caused an error的内容。这就是我添加error_description参数的原因。
如果不想每次都指定错误描述,也可以尝试记录消息和回溯。
a = catch_error(nokodoc) do |doc|
doc.search('#element-1').attribute('href').text
end
def catch_error(doc)
yield doc
rescue => ex
puts doc.title # Or something else that identifies the document
puts ex.message
puts ex.backtrace.join("\n")
end我在这里做了一个额外的更改:将文档作为参数传递,以便rescue可以轻松地记录标识文档的内容,以防这很重要。
https://stackoverflow.com/questions/40598548
复制相似问题