Ошибки
Во время работы программы мы можем столкнуться с различными ошибками, о которых нас любезно оповещает 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