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

Rubyでカスタム例外をマスターする:エラー処理と可観測性を強化する

ソフトウェア開発において、例外のカスタマイズはあまり重視されないことが多いものです。しかし、可観測性ツールでエラーを検知した際に、問題を正確かつ迅速に特定できないとなると、例外に関するより多くの情報や詳細が必要になるでしょう。

本記事では、Rubyで例外をカスタマイズする方法を解説し、エラー情報の不足によって将来発生しうる問題を未然に防ぐ方法をご紹介します。

それでは早速始めましょう!

はじめに:補足事項

この記事は「AppSignalによるRubyのデバッグ」の自然な続編にあたります。デバッグの概要とカスタム例外の入門編については、まずそちらの記事を読むことをおすすめします。

Rubyで例外をrescueする方法

RubyにはExceptionというクラスがあり、エラー処理クラスはすべてこのクラスを継承しています。このセクションでは、独自の例外を作成する前に、Rubyの例外フローの構造をより深く理解していきましょう。

ExceptionはRubyにおける主要な例外クラスであり、rescue Exceptionと書くと、Exceptionを継承するすべての例外を捕捉します。ただし、これはRuby内部で使用される例外まですべて捕捉してしまうため、アプリケーションで使うのはベストプラクティスではありません。

Rubyで例外を捕捉する最も簡単な方法は、以下のようなbegin ... rescueブロックを作成することです。


Exceptionはすべての例外を捕捉してしまうため、必要なエラーだけをフィルタリングして取得できるよう、より具体的なクラスを使うべきです。その一例がStandardErrorクラスです。これは標準的なrescue用クラスで、Ruby内部の例外を無視しつつ、アプリケーションコードのエラーに関連する例外を捕捉します。

StandardErrorを捕捉するには、以下のように記述します。


また、例外クラスを明示しない場合、RubyはStandardErrorクラスが処理する例外を自動的に返します。


Rubyでカスタム例外を作成する場合は、通常StandardErrorを継承したクラスを作成します。これについては次のセクション以降で詳しく説明します。

例外についてさらに学び、どのクラスを継承すべきかを見極めたい方は、Rubyの公式ドキュメントにある例外クラスの一覧をチェックしてみてください。

Rubyの例外に追加情報を持たせる

関連情報を伴わない新しい例外を作成しても、問題のデバッグ(特定と修正)には効果的ではありません。エラーの詳細情報を追加する必要があります。ここでは、オブジェクトからカスタム例外へ情報を受け渡す方法を見ていきます。

まず、ログに残したいデータを受け取るためだけの新しいカスタム例外を作成しましょう。前のセクションで述べたように、カスタム例外はStandardErrorを継承する必要があります。

この実装をテストするには、シンプルなRailsプロジェクトを使うとよいでしょう。Railsプロジェクトのappフォルダ内にexceptionsという名前のフォルダを作成し、そこにcustom_exception.rbというクラスファイルを作成してください。


この例外クラスでは、ログに表示すべき情報を自由に定義できます。今回はデータとして4つの属性を使用します。

  • 例外を番号付けするためのコード
  • 名前
  • 情報メッセージ
  • Rubyがすでに提供している例外の内部詳細情報

次に、begin...rescueブロックを作成し、CustomExceptionをraiseして、パラメータを例外の各属性に渡します。


これは便利そうですね。それでは実装を続けて、このデータを使って例外ログをカスタマイズしてみましょう。

Rubyで例外を拡張する

例外を拡張することで、カスタマイズをより具体的かつ再利用可能なレベルに引き上げることができます。Rubyがさまざまな種類のエラーに対して複数の例外クラスを用意しているように、私たちもシステム内で同じ発想でプログラミングできます。

次に、例外をオーバーライドし、拡張が必要なコンテキストでそれを活用する方法を理解しましょう。

ログから情報を探し出すのは骨の折れる作業です。開発者は「もっとエラーに関する情報や、検索・フィルタリングの手がかりを含めておけばよかった」と自責の念に駆られることがよくあります。こうした機能を提供する監視ツールを使っていないのであれば、意味のあるデータをログに含めておくことで、近い将来きっと自分を救うことになるはずです。

プロのヒント: AppSignalでカスタム例外をセットアップして追跡する方法については、「Debugging in Ruby with AppSignal」の記事にある「AppSignalでRubyの例外をデバッグする」セクションをご覧ください。

以下の例では、ログにおける例外の表示をカスタマイズします。最初は単にデータを見やすく整形するだけだと思うかもしれません。しかし、データに含まれるキーワードこそが、エラーを発見し、アプリケーションを監視する担当者を支援するための重要な手がかりとなるのです。

Gemfileに以下のコードを追加して、colorize gemをプロジェクトに導入しましょう。


bundleコマンドを実行してcolorize gemをインストールし、Railsアプリケーションを起動します。


次に、例外クラスでgemをインポートし、各属性を整形して出力します。こうすることで、重要なエラーをひと目で確認し、素早く見つけられるようになります。


このビジュアルカスタマイズの結果を確認し、さまざまなオプションを試しながら、自分だけのフォーマットやスタイルを作り上げてみてください。

Rubyでカスタム例外をマスターする:エラー処理と可観測性を強化する

まとめと次のステップ

本記事では、Rubyの例外をカスタマイズしてログ上で目立たせる方法を解説しました。他にも多くのカスタマイズが可能ですが、最も重要なのは、アプリケーションに関連する例外を適切に処理することです。そして忘れてはならないのは、Railsがすでにそうしているように、すべての例外に同じフォーマットスタイルを一律に適用しないということです。

それでは、Happy coding!

P.S. Ruby Magicの記事を公開と同時にお読みになりたい方は、Ruby Magicニュースレターを購読すれば、記事を見逃すことはありません!

Rubyでカスタム例外をマスターする:エラー処理と可観測性を強化する

Brena Monteiro(ブレナ・モンテイロ)

ゲスト著者のBrenaは、新人開発者のメンタリングに情熱を注ぐテックリードであり、ハイパフォーマンスなチームの開発とリードにおいて豊富な経験を持っています。スケーラブルなAPIの構築やクラウドサービス間の統合の経験を持ち、進化的アーキテクチャに関心があり、Extended Reality(XR)アプレンティスとしても活動しています。

Brena Monteiroのその他の記事を見る

  1. Railsでクラスター間のアソシエーションをマスターする:disable_joinsによるマルチデータベース対応の完全ガイド

    Railsフレームワークの魅力のひとつは、モデル間のアソシエーション(関連付け)を活用できる点です。Active Recordのアソシエーションを使えば、複雑なSQLクエリを意識することなく、美しいRubyの構文でレコードのコレクションにアクセスできます。しかし、この抽象化が機能するのは、すべてのデータが1つのデータベースに存在している場合だけです。テーブルが複数のデータベースクラスタに分散した瞬間、特定の種類のアソシエーションは動作しなくなります。 本記事では、その境界線がどこにあるのか、そしてRailsがその制約の中で何を提供してくれるのかを詳しく解説します。まず問題が発生する理由と影響を

  2. 初めてのWebスクレイパー構築ガイド 第2回:Mechanizeでリンク・フォーム操作を自動化する

    このチュートリアルでは、Mechanizeを使ってリンクのクリック、フォームへの入力、ファイルのアップロードを行う方法を学びます。さらに、Mechanizeのページオブジェクトを自在に扱う方法や、Google検索を自動化してその結果を保存する方法についても解説します。 目次 単一ページとページネーションの違い Mechanizeとは エージェント(Agent) ページ(Page) Nokogiriメソッドの活用 リンク操作 クリック操作 フォーム操作 単一ページとページネーション これまでのパートでは、Nokogiriを使って単一ページからデータを抽出する方法を見てきました。これは良い基礎