JavaScriptを有効にしてください

[Ruby]rescueとensure

 ·  ☕ 1 分で読めます

概要

  • ruby 3.2

rescueした後にエラーになってもensureは必ず実行されることを初めて知ったのでメモ。

サンプル

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def hoge
  puts 'hoge'
  raise 'hoge error'
rescue => e
  puts 'rescue'
  puts e.message
  raise 'rescue error'
ensure
  puts 'ensure'
  raise 'ensure error'
  puts 'finish'
end

上記を実行すると以下のように出力される

hoge
rescue
hoge error
ensure
RuntimeError: ensure error
from (pry):20:in `ensure in hoge'
Caused by RuntimeError: rescue error
from (pry):17:in `rescue in hoge'
Caused by RuntimeError: hoge error
from (pry):14:in `hoge'

3回エラーが発生していてrescueの中でエラーになっても処理が継続していた。
ensureでのエラーはどうしようもないのでputs 'finish'は出力されていない。
例外処理ではそもそもエラーが起こり得るコードを書くべきではないけど、開発中にタイポしててこんな感じになった。

ドキュメントに以下の記載があった。

ensure 節が存在する時は begin 式を終了する直前に必ず ensure 節の本体を評価します。

「必ず」というのはensureより前で何があっても(resucueでエラーになってても)ということらしい。

単にミスしてただけだが、思わぬところで仕様を学んだ。


書いた人
keee
Webエンジニア

目次