Spec-Zone.ru › Ruby 3.4

Exception Обработка

Исключения перехватываются в блоке begin/end:

begin
  # code that might raise
rescue
  # handle exception
end

Если вы находитесь внутри метода, использовать begin или end не нужно, если только вы не хотите ограничить область перехвата исключений:

def my_method
  # ...
rescue
  # ...
end

То же самое относится к class, module и block:

[0, 1, 2].map do |i|
  10 / i
rescue ZeroDivisionError
  nil
end
#=> [nil, 10, 5]

Вы можете присвоить исключение локальной переменной, используя => variable_name в конце строки rescue:

begin
  # ...
rescue => exception
  warn exception.message
  raise # re-raise the current exception
end

По умолчанию перехватываются StandardError и его подклассы. Вы можете перехватывать определённый набор классов исключений (и их подклассы), перечислив их после rescue:

begin
  # ...
rescue ArgumentError, NameError
  # handle ArgumentError or NameError
end

Вы можете обрабатывать разные типы исключений по-разному:

begin
  # ...
rescue ArgumentError
  # handle ArgumentError
rescue NameError
  # handle NameError
rescue
  # handle any StandardError
end

Исключение сопоставляется с разделом rescue, начиная с верхнего, и обрабатывается только один раз. Если в разделе begin возникнет ArgumentError, он не будет обработан в разделе StandardError.

Вы можете повторно запускать код при перехваченных исключениях:

begin
  # ...
rescue
  # do something that may change the result of the begin block
  retry
end

Выполнение возобновится с начала блока begin, поэтому будьте осторожны и не создайте бесконечный цикл.

Блок rescue — единственное допустимое место для retry; во всех остальных случаях это вызовет SyntaxError. Если вы хотите повторить итерацию блока, используйте redo. Подробности см. в разделе Управляющие выражения.

Чтобы некоторый код выполнялся всегда, независимо от того, было ли вызвано исключение, используйте ensure:

begin
  # ...
rescue
  # ...
ensure
  # this always runs BUT does not implicitly return the last evaluated statement.
end

Вы также можете выполнить некоторый код, если исключение не было вызвано:

begin
  # ...
rescue
  # ...
else
  # this runs only when no exception was raised AND return the last evaluated statement
ensure
  # this always runs.
  # It is evaluated after the evaluation of either the `rescue` or the `else` block.
  # It will not return implicitly.
end

Примечание: если в блоке ensure явно не указан return, блок begin/end вернёт последнее вычисленное выражение перед входом в блок ‘ensure`.

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API