Обработка ошибок в Ruby осуществляется с помощью механизма исключений (exceptions). Это структурированный подход к перехвату и обработке ошибок во время выполнения программы.
Основные ключевые слова для работы с исключениями:
begin
- начало блока, где может возникнуть исключениеrescue
- блок перехвата исключенияensure
- блок, который выполняется всегда (аналог finally
в других языках)raise
- генерация исключенияПример базовой конструкции:
begin
# Код, который может вызвать ошибку
file = File.open('nonexistent.txt')
rescue => e
# Обработка ошибки
puts "Ошибка: #{e.message}"
ensure
# Гарантированное выполнение
file.close if file
В Ruby все исключения наследуются от класса Exception
. Основные подклассы:
StandardError
- стандартные ошибки (чаще всего перехватываются)RuntimeError
- ошибки времени выполнения (по умолчанию для raise
)ArgumentError
- неверные аргументыNameError
- обращение к несуществующей переменной/методуTypeError
- несоответствие типовПример обработки разных типов ошибок:
begin
# Код с потенциальными ошибками
rescue ArgumentError => e
puts "Неверный аргумент: #{e.message}"
rescue ZeroDivisionError => e
puts "Деление на ноль: #{e.message}"
rescue => e
puts "Неизвестная ошибка: #{e.message}"
Можно создавать собственные классы исключений:
class MyCustomError < StandardError; end
begin
raise MyCustomError, "Кастомное сообщение об ошибке"
rescue MyCustomError => e
puts "Поймано кастомное исключение: #{e.message}"
Пример хорошей практики:
def read_config(file_path)
begin
config = File.read(file_path)
JSON.parse(config)
rescue Errno::ENOENT => e
log_error("Config file not found: #{e.message}")
raise "Configuration error"
rescue JSON::ParserError => e
log_error("Invalid JSON format: #{e.message}")
raise "Configuration error"
ensure
# Освобождение ресурсов, если необходимо
end
end
У каждого исключения есть полезные методы:
message
- текст ошибкиbacktrace
- стек вызововcause
- исходное исключение (для цепочки исключений)Пример использования:
begin
# Код с ошибкой
rescue => e
puts "Ошибка: #{e.message}"
puts "Стек:"
puts e.backtrace.join("\n")
Ruby позволяет повторить блок begin-rescue:
attempts = 0
begin
attempts += 1
# Код с возможной ошибкой
rescue NetworkError => e
retry if attempts < 3
raise "Слишком много попыток"
Резюмируем: обработка ошибок в Ruby - мощный и гибкий механизм, который при правильном использовании делает код надежным и предсказуемым. Ключевые аспекты - это специфичность обработки, правильное логирование и освобождение ресурсов.