導入
第8章で begin / rescue / raise を学びました。実務では、エラーの種類ごとに自分の例外クラスを作り、rescue で種類を見分けて対応を変えます。エラーに名前がつくと、原因が一目で分かり、対処も書きやすくなります。
説明
StandardError を継承したクラスを作るだけで、独自の例外になります。raise 例外クラス, "メッセージ" で発生させます。
class AgeError < StandardError; end
def check(age)
raise AgeError, "年齢が不正: #{age}" if age < 0
"OK: #{age}"
end
begin
puts check(20) # OK: 20
puts check(-1) # ここで AgeError が発生
rescue AgeError => e
puts "エラー: #{e.message}"
end
rescue は例外クラスを指定できるので、種類ごとに違う対応を書けます。上から順に、最初に一致したものが実行されます。
class NotFoundError < StandardError; end
class PermissionError < StandardError; end
def access(user)
raise NotFoundError, "ユーザーがいません" if user.nil?
raise PermissionError, "権限がありません" if user == "guest"
"ようこそ、#{user}さん"
end
["admin", "guest", nil].each do |u|
begin
puts access(u)
rescue NotFoundError => e
puts "404: #{e.message}"
rescue PermissionError => e
puts "403: #{e.message}"
end
end
標準の rescue => e(クラス指定なし)は StandardError とその子孫をすべて捕まえます。まず種類ごとに rescue を並べ、最後に汎用の受け皿を置くのが実務の型です。
やってみよう
新しい例外クラス(例:TooLongError)を作って raise し、専用の rescue で捕まえてみましょう。rescue の順番を入れ替えると挙動がどう変わるかも試してください。
演習
TooBig という例外クラス(StandardError を継承)を定義し、raise TooBig, "over" を begin / rescue TooBig => e で捕まえて、e.message を puts で表示してください(over になります)。
ヒント1を見る
class TooBig < StandardError; end の1行で例外クラスを作れます。