LoginSignup
17
17

More than 5 years have passed since last update.

「正しい例外の使い方」の説明は難しいが、「間違った例外の使い方」の説明は簡単だ。

Last updated at Posted at 2017-08-16

タイトルは釣りです。

PHPの現場で公開されているPHPの例外 というPodcastを聞いていて、考えたこと。
お断り: 以下は個人の見解であって、所属先の見解ではありません。

聞けば聞くほど、「正しい例外の使い方」というのは難しいものだと思いました。

例外関連の話題となると例外とは何か? とか、例外の正しい使い方は? となるわけですが、大抵の場合は禅問答のような難しい話題になりがちです。
参考: 例外設計における大罪

「だから例外は難しい。」で思考停止にるのではなく、「間違った例外の使い方」を避けるようにしていけば地雷を踏むことはないはずです。

自分で投げた例外を自分自身でcatchしてはいけない。

関数・メソッド内で投げた例外を自分自身でcatchするなら、例外を投げる必要はありません。
例外は自分自身(関数・メソッド)以外の誰に向かって投げるものです。

それは例外を goto の代わりに使っている証拠です。素直に goto を使いましょう。

例外が必ずおきることを前提にしてはいけない。

例外は起きるかもしれないことを前提にした機構です。
必ず例外が起きることを前提としたコードは書いてはいけません。

極端な例
try {
    while(true){
        // いつか例外をthrowする。はず…。
        foo();
    }
} catch (Exception $e) {
}

foo() の中で例外が発生しないと、無限ループになります。

理由を明記せずに、例外を握りつぶしてはいけない。

発生した例外を catch して、そのまま握りつぶすことがあります。

その理由が明記されていないと、その理由や、ただ単にコーディング漏れではないことを判断できません。
なぜその例外を握りつぶして良いかコメントに記述しましょう。

(以下、おまけ)PHP組み込みExceptionの分類案

Podcast内で話題になっていた、組み込みExceptionのLogicalExceptionRuntimeExceptoinという大分類の違いをどうとらえるかです。

私としては「実行時にだけ発生するようなエラー」で分類してしまったのが失敗の元だったと考えます。
http://php.net/manual/ja/class.runtimeexception.php

例外(コンパイルエラーも含む)は常に実行時にしか発生しえないので、この分類自体あまり意味があるとは思えません。

こんな感じの分類を提案したいところです。
上記に従い、例外は「例外は自分自身(関数・メソッド)以外の誰に向かって投げるもの」とすれば、関数(メソッド)の呼び出し関係が切り口になります。

  1. 呼び出し側に責任がある
    1. ランタイムが判断できる
      • 存在しないメソッド(関数)を呼び出した場合
      • 引数が足りない場合
      • 引数の型エラー(Type Mismatch)の場合
      • 0除算エラーの場合
      • アンダーフロー・オーバフロー発生の場合
      • 制御構造(if, for, foreach)への不正な引数。1
    2. ランタイムが判断できない
      • 引数の値が(ビジネスロジックの観点で)不正の場合
  2. 呼び出された側に責任が無い
    1. 実装側に責任がある
      • Assesionに引っかかった場合
    2. 実装側に責任が無い
      • メモリ不足が発生した場合
      • ファイルシステム関連のエラーが発生した場合
      • I/O(ディスク、ネットワーク、DB、外部API)エラーが発生した場合
      • シグナル割り込み発生の場合

それでは良い例外ライフを。


  1. ここでは、演算子は関数(メソッド)とみなしています。配列の参照 [] も演算子とみなしています。 

17
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
17