#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
блоками), чтобы выбрать, следует ли вам немедленно отказаться, подождать и повторить попытку или повторить попытку немедленно.