Ruby — Срок выполнения истек

#ruby #exception-handling

#ruby #исключение

Вопрос:

У меня есть код ruby, подобный этому:

 begin
  doc = Nokogiri::HTML(open(url).read.strip)
rescue Exception => ex
  log.error "Error: #{ex}"
end
  

И я получаю журнал как:

 ERROR -- : Error: execution expired
  

Я хочу, чтобы блок повторно выполнялся до тех пор, пока он не увенчается успехом.

Как я могу это сделать?

Комментарии:

1. Прежде всего попробуйте открыть URL отдельно от передачи его в nokogiri, поскольку это может упростить исправление ошибок

2. Вы имеете в виду это?: doc = open(url).read.strip doc = Nokogiri::HTML(doc)

3. Нет, я имею в виду, data = open(url).read.strip тогда в следующей строке doc = Nokogiri::HTML(data)

4. И если вы действительно хотите вернуться к begin из rescue , используйте retry (но следите за бесконечными циклами).

5. ОК. то же самое я пытался спросить у вас. но я забыл отформатировать code 🙂

Ответ №1:

Я немного расширю свой комментарий. Вы можете использовать retry , чтобы вернуться к begin :

 begin
  doc = Nokogiri::HTML(open(url).read.strip)
rescue Exception => ex
  log.error "Error: #{ex}"
  retry
end
  

Это будет продолжать попытки (и регистрировать ошибки) до тех пор, пока это не сработает или вы вручную не уничтожите его. Это, вероятно, не то, что вы хотите, хотя одна небольшая ошибка отправит вас в бесконечный цикл. Простой способ обойти это — позволить ему попробовать, скажем, 10 раз, а затем отказаться:

 MAX_ATTEMPTS = 10

doc = nil
begin
  doc = Nokogiri::HTML(open(url).read.strip)
rescue Exception => ex
  log.error "Error: #{ex}"
  attempts = attempts   1
  retry if(attempts < MAX_ATTEMPTS)
end

if(doc.nil?)
  # Do something about the persistent error
  # so that you don't try to access a nil
  # doc later on.
end
  

Что-то подобное попытается сделать несколько раз, а затем откажется. Вы также можете поместить sleep вызов перед retry , если хотите немного подождать перед следующей попыткой или исследовать исключение (возможно, с несколькими rescue блоками), чтобы выбрать, следует ли вам немедленно отказаться, подождать и повторить попытку или повторить попытку немедленно.