LINUX.ORG.RU

ruby, обработка ошибки тайм-аута

 , ,


0

1

Скриптик обходит по очереди каждый узел (~1075 шт.) и выполняет на нем определенные действия. Проблема в том, что как только скрипт доходит до «лежачего» узла (а они есть практически всегда) - его выполнение прерывается. Список узлов находится в массиве, скрипт работает так:

array.each {|ip| host=Net::Telnet::new("Host" => ip, "Timeout" => 10, "Waittime" => 1, "Prompt" => /[#>\]-]/);
                                 пачка команд}. 
Как обработать ошибку тайм-аута так, чтобы выполнялся переход к следующему элементу массива, а не полное завершение работы цикла? Так же интересует общее решение проблемы - я бы хотел вести лог «необработанных» узлов (сейчас все сообщения об ошибках логируются с помощью $stderr, но само сообщение для меня бесполезно - мне нужен адрес лежачего коммутатора).

Ошибка тайм-аута

Как обработать ошибку тайм-аута

Что такое «ошибка тайм-аута»? Выброс исключения? Если так, то поступать как указали выше: обернуть команду в begin-rescue-end. Лучше с указанием класса исключения.

Camel ★★★★★
()
Ответ на: Ошибка тайм-аута от Camel

«ошибка тайм-аута» - это когда вызываемый узел недоступен/не существует. По умолчанию ожидается 10 секунд, после чего выполнение скрипта прерывается. telnet.rb:355:in `rescue in initialize': timed out while opening a connection to the host (Timeout::Error) - такого рода. По поводу «обернуть команду в begin-rescue-end: у меня в блоке есть фигурные скобки {} - они сойдут за begin/end? Или еужно делать именно begin-rescue-end внутри блока {}? Как узнать класс исключения?

hasculdr
() автор топика
Ответ на: комментарий от hasculdr

у меня в блоке есть фигурные скобки {} - они сойдут за begin/end?

Нет, это разные вещи.

Или нужно делать именно begin-rescue-end внутри блока {}?

Нет, «begin-rescue-end» перехватывает все исключения вызванные кодом внутри, лучше помести «array.each» внутрь «begin-rescue-end», будет читабельнее.

Как узнать класс исключения?

Он идёт в вместе с описанием ошибки в errout, в твоём случае это Timeout::Error

Deleted
()
Ответ на: комментарий от hasculdr

И как называется класс/модуль для rescue (required '...')?

«rescue» это кейворд, идёт вместе с ruby-core, скорее-всего в классе Exception

Deleted
()
Ответ на: комментарий от Deleted

лучше помести «array.each» внутрь «begin-rescue-end», будет читабельнее.

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

И вообще тут явно не хватает многопоточности.

TDrive ★★★★★
()

Во-первых, код написан каким-то мудаком, ибо длина одной строки 110 символов. Во-вторых, это называется исключением. Его можно поймать. Типа как-то так:

array.each do |ip|
  begin
    host=Net::Telnet::new( "Host" => ip,
                           "Timeout" => 10,
                           "Waittime" => 1,
                           "Prompt" => /[#>\]-]/ )
  rescue Timeout::Error
    STDERR.puts "Time out error " + ip
  end
end
nikolnik ★★★
()
Ответ на: комментарий от hasculdr

Прощать тебя будут те, кто будут твой код читать. Синтаксически руби так сделан, что любой код можно записать одной строкой, но так делать не стоит. Ну так получилось починить или как?

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

Удалось. Спасибо всем.

buffer.each { |ip|
begin
  host=Net::Telnet::new("Host" => ip,
                          "Timeout" => 5,
                          "Waittime" => 1,
                          "Prompt" => /[#>\]-]/)
  host.login(username="login", password="password")
  host.close
rescue Net::ReadTimeout #возобновляем обход массива с коммутаторами при неподходящих логине/пароле
$stderr.puts "Нестандартные логин/пароль на " + ip #записываем в лог ошибок ip-адрес недоступного узла
rescue Timeout::Error #возобновляем обход массива с коммутаторами при найденном не отвечающем узле
$stderr.puts ip+" недоступен"  #записываем в лог ошибок ip-адрес недоступного узла
end
}

hasculdr
() автор топика
Ответ на: комментарий от hasculdr

Ловит любое исключение выражения f(ip) и в случае переходит к следующей итерации оператором next

nikolnik ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.