Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyの例外処理入門:raiseとrescueの基本をマスターしよう

例外(Exception)とは、アプリケーションで発生した例外的な状況に関する情報を保持する特殊なデータ構造です。プログラムが特定の状況への対処方法を判断できず、実行を継続できないときに送られるシグナルが例外です。Rubyでは、このようなシグナルを送ることを「例外を発生させる(raise)」と呼びます。

raise 'これは例外です'
 
puts "このメッセージは表示されません。"

例外の動作を最も手軽に確認する方法は、自分で例外を発生させてみることです。raiseメソッドにメッセージを渡して呼び出すと、Rubyはそのテキストを説明文として持つRuntimeErrorを生成します。同時に、コード内のどこで例外が発生したかを示すスタックトレースも追加されます。

$ ruby raise.rb
raise.rb:1:in `<main>': これは例外です (RuntimeError)

上記のサンプルスクリプトを実行すると、予想どおり、例外が発生した後にはメッセージが表示されないことがわかります。これは、未処理(未捕捉)の例外がクラッシュを引き起こしてプログラムの実行を停止させるためです。これにより、あるタスクの完了に失敗した後もアプリケーションが動作し続けてしまう事態を防いでいます。

さまざまな種類の例外

Rubyは内部では、問題が発生した際に例外を発生させます。たとえば、数値をゼロで割ろうとすると例外が発生します。

irb(main):001:0> 42/0
ZeroDivisionError: divided by 0
        from (irb):1:in `/'
        from (irb):1
        from /Users/jeff/.asdf/installs/ruby/2.3.0/bin/irb:11:in `<main>'

この場合、例外の種類は先ほどのRuntimeErrorではなく、ZeroDivisionErrorです。Rubyの例外階層を構成する例外クラスは数十種類あり、それぞれ異なる状況で発生します。

RuntimeErrorは比較的汎用的な例外クラスですが、より具体的なものもあります。たとえば、存在しないメソッドを呼び出そうとするとNoMethodErrorが発生し、既存のメソッドに誤った引数が渡された場合にはArgumentErrorが発生します。

例外のrescue(捕捉)

ほとんどのアプリケーションには、例外から回復する仕組みが必要です。Webアプリケーションでは、ユーザーがフォームに不正なデータを送信したときにエラーが起こることがあります。このような場合、Webサーバー全体をクラッシュさせるのではなく、ユーザーにエラーメッセージを表示するのが正しい挙動です。

こうしたケースでは例外が発生しても、呼び出しスタックの最上位に到達する前にWebサーバーがそれをrescue(捕捉)するため、例外がアプリケーションのクラッシュにつながることはありません。

begin
  raise 'これは例外です'
rescue RuntimeError => exception
  puts "例外を捕捉しました: #{exception.inspect}"
  # => "例外を捕捉しました: #<RuntimeError: これは例外です>"
end
 
puts "このメッセージ*は*表示されます。"

先ほどの例をbegin/rescueブロックで囲むことで、例外はそのまま放置されず、アプリをクラッシュさせることもなくなります。代わりにrescueブロックが実行され、この例では例外が捕捉されたことを伝えるメッセージが出力されます。また、アプリのクラッシュが防がれるため、最後のメッセージきちんと表示されます。

この例ではRuntimeErrorのみを明示的にrescueしているため、それ以外のエラーは捕捉されません。どのエラーをrescueするかを具体的に指定することにはメリットがあります。エラーの種類ごとに異なる処理を行えるからです。同時に、必要以上に多くの例外をrescueしないよう注意することも重要です。

例外処理についてさらに詳しく学びたい方や、例外を適切にrescueするためのコツを知りたい方は、Ruby Magicの例外処理入門記事もぜひご覧ください。

Rubyでの例外の発生や捕捉について疑問がある方は、@AppSignalまでお気軽にお問い合わせください。この記事が役立ったかどうか、また他に詳しく知りたいトピックがあれば、ぜひお聞かせください。

  1. Rubyで例外にコンテキストデータを追加する3つの方法

    標準のバックトレースやエラーメッセージだけでは、エラーの原因を特定するのに十分な情報が得られないことがあります。そんなときに役立つのが、例外への追加データの付与です。幸い、Rubyではこれをとても簡単に実現できます。 エラーメッセージをカスタマイズする 例外にコンテキスト情報を加える最もシンプルな方法は、メッセージそのものに情報を組み込んでしまうことです。次の例では、発生した例外を捕捉し、新しいメッセージを付けて再送出しています。 begin raise foo rescue => e raise e.class, bar end # RuntimeError: bar

  2. RubyのTracePointで複雑な例外の挙動を調査する方法

    例外の挙動を把握するのは、時に非常に難しいものです。特に大規模なアプリケーションではその傾向が強まります。既存のプロジェクトでコードを書いていて、例外をraiseしたのに奇妙なことが起こった経験はありませんか?例外がどこかで握りつぶされている。環境変数が書き換えられている。あるいは、自分のraiseした例外が別の例外に包まれてしまう——そんなケースです。 この記事では、TracePointを使ってアプリケーション内の例外についてより詳しい情報を得るためのシンプルな方法を紹介します。例外が握りつぶされていたとしても、その動きを追跡できます。 わかりやすい例:コントローラでrescueできない