例外の取り扱い (Exception)

rescue で型を指定しなかった場合、 StandardError (とそのサブクラス) のみがキャッチされる。

begin
  raise "Error"                 # will be caught
  raise Exception.new("Error")  # will not be caught
rescue => e
  puts e.message
end
  • StandardErrorException のサブクラス
  • RuntimeErrorStandardError のサブクラス
  • RuntimeError < StandardError < Exception
  • Exception はシステム関係の例外も含む
  • アプリケーションレベルの例外は StandardError (とそのサブクラス) を使うべき

参考:

ruby の例外についてまとめてみた – Qiita

例外処理 – Qiita

Ruby の例外処理 (begin – rescue と raise) をもう一度きちんと確認してみた。- Qiita

Exception

全ての例外の祖先のクラス。

begin
  raise Exception.new("Error")
rescue Exception => e
  puts e.message
end

参考:

class Exception (Ruby 2.5.0)

instance method Exception#message (Ruby 2.5.0)

instance method Exception#backtrace (Ruby 2.5.0)

Exception.new

例外オブジェクトを生成して返す。

new(error_message = nil) -> Exception
exception(error_message = nil) -> Exception
error_message
エラーメッセージを指定する。Exception#message が返す値となり、デフォルトの例外ハンドラで表示される。
e = Exception.new("This is an error.")
p e             # => #<Exception: This is an error.>
puts e.message  # => "This is an error."

参考:

singleton method Exception.exception (Ruby 2.5.0)

StandardError

通常のプログラム (アプリケーション) で発生する例外を束ねるクラス。

rescue 節でクラスを省略した場合、StandardError とそのサブクラスの例外が捕捉される。

参考:

class StandardError (Ruby 2.5.0)

Ruby で独自例外を定義するときは StandardError を継承する | Hack Your Design!

自前の例外クラスで StandardError を継承する | deadwood

ruby でエラーコード付きの独自例外クラスを作成 + カスタム logger で出力 | のんびり SE の議事録

Ruby で自前の例外クラスを作るとき Exception ではなく StandardError を継承する理由 | yarb の日記

RuntimeError

特定の例外クラスに該当しないエラーが起こった場合に発生する例外。

Kernel.#raise で例外クラスを指定しなかった場合には RuntimeError が発生する。

raise "Error"  # throw `RuntimeRrror`

参考:

class RuntimeError (Ruby 2.5.0)

ArgumentError

参考:

class ArgumentError (Ruby 2.5.0)

raise

例外 RuntimeError を発生させる。

raise "Error"

例外 SyntaxError を発生させる。

raise SyntaxError, "Invalid syntax"
raise SyntaxError.new("Invalid syntax")

最後の例外を再発生させる。rescue 節で例外を外部のコードに伝搬させるために使用する。

raise

参考:

module function Kernel.#fail (Ruby 2.5.0)

raise – 制御構造 (Ruby 2.5.0)

begin … rescue … ensure … end

begin
  expressions...
[rescue [error_type, ...] [=> evar] [then]
  expressions...]...
[else
  expressions...]
[ensure
  expressions...]
end

begin から rescue までが例外の捕捉対象 (本体) となる。

例外が指定した例外クラスのインスタンス (サブクラスを含む) である場合に、該当する rescue 節に捕捉され、その rescue 節が実行される。

例外が発生しなかった場合に else 節が実行される。

例外の発生・非発生に関わらず、ensure 節は最後に必ず実行される。

begin 式全体の評価値は、本体 / rescue 節 / else 節のうち最後に評価された文の値となる。各節において文が存在しなかったときの評価値は nil となる。ensure 節の値は無視される。

クラス / モジュール / メソッドの定義では、begin キーワードを使うことなく定義全体 (本体) を処理対象として rescue 節、else 節、ensure 節によって例外を処理することができる。

参考:

begin – 制御構造 (Ruby 2.5.0)

rescue 修飾子

expr1 rescue expr2

参考:

begin – 制御構造 (Ruby 2.5.0)

特殊変数

$!$@ は例外発生時、Kernel.#raise によりセットされる。

$! は最後に発生した例外が格納される。

$!

$@ は最後に例外が発生したソースコード上の位置が格納される。

$@

参考:

variable $! (Ruby 2.5.0)

variable $@ (Ruby 2.5.0)

backtrace

参考:

エラーを rescue して、rescue しない場合と全く同じエラーメッセージを出力する – Qiita

instance method Exception#backtrace (Ruby 2.6.0)

cause

参考:

Ruby で RuntimeError (例外) のバックトレースを最初の raise までさかのぼって出力する – Qiita

instance method Exception#cause (Ruby 2.6.0)

e2mmap

例外にエラーメッセージフォーマットをマッピングするためのライブラリ

参考:

library e2mmap (Ruby 2.6.0)

タグ:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です