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.