Quantcast
Viewing all articles
Browse latest Browse all 100

Rubyで学ぶ例外処理

自分の手である程度動くコードが書けるようになってきた際、次のステップとし待ち構えているのが例外処理ではないでしょうか。
実際、業務などでプログラムを書く際には、プログラムやアプリケーションがクラッシュしないように適切に例外処理/エラーハンドリングをすべきシーンが多々あります。

今回はRubyを例にして例外処理についてまとめました。

例外処理とは

wiki大先生によると例外処理とは、

プログラムの上位の処理から呼び出されている下位の処理で継続不能、または継続すれば支障をきたす異常事態に陥ったとき、制御を呼び出し元の上位の処理に返し安全な状態になるよう回復処理をすること。その際に発生した異常のことを例外と呼ぶ。
だそうです。

また、継続不能や継続すると問題になる様な状態としては下記が挙げられています。

- ハードウェアの故障
- オペレーティングシステム等、システムの設定ミス
- ライブラリの欠損
- ユーザーの入力間違い
  - 数値入力を要求している場合での、英単語の入力
  - 存在しないファイルの指定
- 許されない演算(0での除算や実数演算で解が虚数になる演算など)
- 割り当てられていない記憶領域へのアクセス
  - 不正な値が与えられたポインタで参照する、或いは機械語レベルで不正な値が与えられたインデックスレジスタ等を用いてメモリ参照することとなった場合
  - ページフォールト
- プログラミング言語において、何も参照していないハンドルやポインター(Nullポインタ)を参照して操作しようとした場合(例としてJavaにおけるNullPointerExceptionなど)。

超ざっくりいうと、ユーザー側の不備(登録フォームの入力漏れなど)というよりは、システム側の不備(仕様の考慮漏れ、バグ、外部連携先のサービスがダウンしてるなど)によって発生した不具合からシステムが安全に回復するための処理のことを言います。

例外処理を実装する意義

プログラム/アプリケーションをクラッシュさせない

重大な例外が発生した際に例外処理を実装していないと、プログラムやアプリケーションが異常終了につながる可能性があります。
そうなると例外発生後にユーザーがシステムを正常に使用できないことはもちろん、システムを提供する企業にとっては甚大なる損害になります。

エラーの早期発見とシステム改修につなげる

例外発生を適切に捕捉してログに残したりslackなどに通知する仕組みを作っておくことで、不具合の早期発見や修正につなげることができます。

Rubyにおける例外処理

書き方

下記のようにbegin ~ rescue ~ endで処理をサンドイッチするのが基本です。
rescue節で捕捉したいエラーのクラスを指定します。
指定がない場合にはStandardErrorが捕捉されます。

begin
  # 例外が起こりそうな処理
rescue StandardError => error # 捕捉したい例外のクラスを記載する。記載しない場合にはStandardErrorが使われる
  # 例外が起こった際の処理(ココで上手いことエラーから復帰するようにする)
  # 変数'error'の中にエラーに関する情報が入っているのでこれを使う
end

メソッドに直接rescueを付けることもできます。

def devide(num1, num2)
  num1 / num2 #
rescue => error
  puts "error is occured! #{error}"
end

例外の発生有無に関わらず共通処理をしたい場合には下記のように書きます。

begin
  # 例外が起こりそうな処理
rescue => error
  # 例外が起こった際の処理(ココで上手いことエラーから復帰するようにする)
ensure
  # 例外の有無にかかわらずその後実行したい処理を書く
end

注意点

rescue内部でエラーの情報を活用する(例外を握り潰さない)

例外処理は「begin ~ rescue ~ endで囲めばそれで良い」というものではありません。
例外処理の中で適切に例外を捕捉し、それをログに残したり通知する必要があります。

捕捉する例外は絞る

Rubyの場合はExceptionクラスが例外の大元のクラスですが、このクラスには膨大なサブクラスが付いているのでrescue Exception => errorなどとすると捕捉する必要のないエラーまで取得してしまいます。
そのため、例外処理を実装する上では、どのような例外を捕捉したいのかを考えた上で、その例外に対して捕捉するようにするべきです。

何でもかんでも例外処理を挟もうとしない

例外処理の大切さがわかったからといって、ありとあらゆる処理に例外処理を挟むのは、パフォーマンスや可読性の観点で現実的ではありません。
例外の発生度合い、発生した際のクリティカル度合いなどを鑑みた上で、処理を入れるのが良いのではないかと思います。

参考


Viewing all articles
Browse latest Browse all 100

Trending Articles