Ошибки
Во время работы программы мы можем столкнуться с различными ошибками, о которых нас любезно оповещает Ruby. Удобно, когда тебе не нужно включать дебаг, а досаточно просто внимательно прочитать ошибку и ее исправить.
Отлов ошибок
Но одно дело натыкаться на эти ошибки во время разработки, а другое дело, когда эти ошбки видит наш конечный пользователь. Для того, чтобы нам защититься от неожиданного поведения программы существует понятие отлов ошибок. В Ruby для этого мы можем воспользоваться конструкцией begin ... end.
user_input = gets.chomp.to_i
puts 10 % user_inputпростейшая программа, которая получает пользовательский ввод и делит 10 на полученное число. Но вот не задача, пользователь вводит 0, а как мы знаем, делить на 0 нельзя. В итоге получим ошибку ZeroDivisionError. Давайте исправим ситуацию:
user_input = gets.chomp.to_i
# все что находится между begin и rescue будет проверяться на ошибки
# если ошибка срабатывает, то начинает работать логика между rescue и end
begin
puts 10 % user_input
# после rescue мы указываем ошибку, которую мытаемся отловить
# err - объект класса ошибки которую отлавливаем
rescue ZeroDivisionError => error
# Важно в случае ошибок не просто обработать и дать корректный ответ
# но и не потерять информацию об ошибке, например написать ее в консоль
p error
puts 0
# количество отлавлиемых ошибок может быть сколько угодно
# Если ошибка не является объектом класса первой отлавливаемой ошибки, значит проверяется следующий rescue тд.
rescue ArgumentError => error
puts "Ошибка: Некорректный формат введенных данных. #{error.inspect}"
end
# если мы отловили ошибку, то после кода внутри rescue программа начем работать дальше
puts "finish"В целом begin ... rescue ... end по своему виду очень похож на if ... elsif ... else ... end, только в одном случае мы проверяем условия, а в другом тип ошибки.
Создание собственных
Как Ruby выкидывает нам свою ошибку, так и мы можем выкидывать свои собственные ошибки.
Для начала создадим класс ошибки и унаследуем его от StandardError:
class MyError < StandardError
def initialize(message)
# любая ошибка имеет внутри себя сообщение об ошибке, которое в случае чего показывается в консоли
# например ZeroDivisionError имеет текст "divided by 0"
super(message)
end
endТеперь нам нужно выбросить эту самую ошибку
def example(arg)
if arg > 10
# выброс ошибки отличается от создание объекта
# нсачала пишем raise, потом класс ошибки, потом текст, который будет передан в метод initialize
raise MyError, "helpful description for error"
else
puts "It is argument - #{arg}"
end
end
begin
# Сначала в консоль распечатается 'It is argument - 1'
example(1)
# Здесь уже сработает наша ошибка
example(20)
# Отловили нашу ошибку
rescue MyError => error
# Теперь в консоль напечаталось 'It is MyError - helpful description for error'
puts "It is MyError - #{error.message}"
endДополнительный материал
Last updated