Правильная обработка ошибок в Ruby - PullRequest
0 голосов
/ 03 декабря 2011

У меня есть блок кода, который выглядит следующим образом:

def create_page_object(url)
  begin
    page = Nokogiri::HTML(open(url))
  rescue
    puts "page not loaded"
  end
end

, а затем я вызываю его через:

result.each do |url|
  page = create_page_object(url)
  content = make_content(page)
end

Теперь в терминале я вижу "страница не загружена"а затем Руби взрывает меня.Как я могу сказать: «Если страница не загружена, остановитесь и перейдите к следующему элементу».

Обновление:

Научное определениеof Blowing Up:

test.rb:70:in `get_title': undefined method `xpath' for nil:NilClass (NoMethodError)
    from test.rb:40:in `block (2 levels) in process'
    from test.rb:35:in `each'
    from test.rb:35:in `block in process'
    from test.rb:32:in `upto'
    from test.rb:32:in `process'
    from test.rb:138:in `<main>'

То, что я считаю, происходит потому, что не загружается, там не задана переменная страницы, которая равна нулю и выбрасывается в функцию make_content.

Ответы [ 5 ]

2 голосов
/ 03 декабря 2011

Есть много способов справиться с этим, так что вот еще:

def create_page_object(url)
  begin
    page = Nokogiri::HTML(open(url))
    yield page
  rescue
    puts "page not loaded"
  end
end

result.each do |url|
  create_page_object(url) { |page| content = make_content(page) }
end

Но если вам нужно content вне блока:

content =  nil
result.each do |url|
  create_page_object(url) { |page| content = make_content(page) }
end

Или вы можете поместить больше content логики обработки внутри блока:

result.each do |url|
  create_page_object(url) do |page|
    content = make_content(page)
    # do interesting things with 'content' here
  end
end
2 голосов
/ 03 декабря 2011

Спасательный блок возвращает вывод puts (то есть nil), вы должны убедиться, что у вас есть документ, прежде чем работать с ним. Также обратите внимание, что при спасении вы должны явно вернуть nil, чтобы уточнить, какой метод возвращает в этой ветке. Я бы написал:

def create_page_object(url)
  begin
    page = Nokogiri::HTML(open(url))
  rescue
    puts "page not loaded"
    nil
  end
end

result.each do |url|
  if (page = create_page_object(url))
    content = make_content(page)
  end
end

Я не знаю ваших особых потребностей, но обычно плохая идея делать «упреждающие» спасения. Спасайтесь, когда у вас есть что-то полезное, иначе вы мешаете делать это на более высоких уровнях.

1 голос
/ 03 декабря 2011

Попробуйте это:

def create_page_object(url)
  begin
    Nokogiri::HTML(open(url))
  rescue
    puts "page not loaded"
  end
end

result.each do |url|
  page = create_page_object(url)
  next if page.nil?
  content = make_content(page)
end

В Ruby последним выражением в методе является возвращаемое значение, так что вы можете опустить свое назначение.puts метод ничего не возвращает, и вы получаете nil в случае исключения.

1 голос
/ 03 декабря 2011

Один из способов сделать это - вернуть nil в create_page_object (url), если вам пришлось его спасать, и вернуть true, если он загружен в Nokogiri :: HTML (open (url)). Таким образом, вы можете проверить, равен ли он нулю, и просто в следующем цикле, если это так. Пример:

def create_page_object(url)
  begin
    page = Nokogiri::HTML(open(url))
  rescue
    puts "page not loaded"
    return nil
  end
end

и

result.each do |url|
  page = create_page_object(url)
  next if page.nil?
  content = make_content(page)
end

Я удивлен, что «Nokogiri» выдает исключение, если страница не загружается, а не возвращает нулевой объект, но если это так, то этот метод должен сделать это за вас. Удачи.

0 голосов
/ 05 марта 2016

Вы можете попробовать использовать "rescue OpenURI :: HTTPError => e" вместо просто "rescue".

...