ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

エラー処理ポリシー

個人的には「エラー処理」と一口に片づけること自体が本来はあまり好きじゃない。「エラー」という言葉の意味に惑わされ、本業のとあるPrjで概念が顧客と一致せずかなり長い間言葉のやりとりで齟齬を生じていたからだ。対象の範囲が広がりすぎていて好きじゃない。多分状態や対応する挙動など、「異常」に対する複数の概念を包含してるからかもしれない・・・。

YakiBiki・・・というかいろいろなシステムでもそうだと思うけど、入力・内部処理・出力の組み合わせでプログラムは動いてる。YakiBikiの場合で言えば入力はHTTPリクエスト、出力はHTML。でもこれは階層化されていて、例えばDAOレイヤーであれば入力はデータ配列、内部処理はPHPのファイル入出力と文字列処理、出力はデータ配列か真偽値になる。
で。ぐだぐだ考えたあげく、ようやく以下の感じに落としどころを持って行くことにする。
大体三種類の「エラー」が有りうる。

  • 入力値のフォーマットミス。数値指定のIDが文字列になっている、Validationエラー、など。
  • ロジックとしての例外処理。例えば存在しないモジュール名が入力された、指定されたIDのデータが見つからない、など。
  • PHP関数がこけた時(型が違う時とか)。ファイルI/Oでの失敗時。データファイルのフォーマットが違う時。

これはそれぞれ、対応すべきアクションがある。

  • 入力値のフォーマットミス→ユーザーに報せる。あるいはシステムの振る舞いに依存する。(デフォルトアクションをするなど)
  • ロジックとしての例外処理→システムの振る舞いに依存する。
  • PHP関数が・・・→これが二つに分かれると思う。
    • 発生する事がロジックとして想定されている時:システムの振る舞いに依存する。(ファイルI/OやソケットI/Oでのリトライ処理、あるいはfopenしようとして失敗することがロジックとして想定されている時)
    • 発生する事が想定されていない時:引数の型が違う時。I/Oなどの関数で、失敗することがシステム上ありえない時。
      • 例1 : 全て正常に動いているYakiBikiのDAOで、突然データのカラム数がおかしくなったとき。
      • 例2 : include/require_once()したファイルが見つからない。

で、アクションに着目するとおおよそ結局、次の二種類に分かれる。

  • 開発者を呼ぶ必要が無いエラー:入力値系、ロジック系。ユーザーにとって意味のある出力を返すもの。最終的に、ユーザー側で何らかのアクションを取り、再度システムに入力をできるようにする余地のあるもの。
    • 例:想定外入力値:ユーザー側で入力値を確認し、再度入力できる。
    • 例:重複値検出:同上。
    • 例:0件系:同上、またはアプリケーションとしての別のアクションをユーザーが選択できる。
    • 例:I/O系リトライエラー:これは微妙。ユーザー側のアクションとして、時間をおいてやりなおしたり、ユーザーの動ける範囲で何らかの対処が可能な物。
  • 開発者を呼ぶ必要が有るエラー:前掲の「発生することが想定されていない時」に相当する。ユーザーレベルじゃどうにもならないエラー。例えばファイルパーミッションエラーもコレに相当する。OSのコンソールにログインしてファイル操作をしないとならない。つまり、システムだけではどうにもならずその中まで入らないとできない。

前者については全てプログラミングのロジックとして実装できるし、そもそも全部ロジックでハンドリングしているものだろう。だってシステムの入出力の取り扱いそのものなのだし*1。つまりこれらのエラーは、出力レイヤーで見た場合には通常の出力ルートと変わらない挙動になる。出力も内部処理のレイヤーで制御しているものと捉えられるからだ。
一方の後者、については、出力レイヤーで見た場合にも異常事態である。内部処理のレイヤーからの通常制御が期待できない。システムやアプリによっては全て内部処理のレイヤーで統括している場合もあるのだろうけど、そもそも内部処理レイヤーの実行自体がこける可能性も後者には含まれている。よって、最悪出力レイヤー自体もこける可能性がある。このときの出力は、ユーザー側だけではどうにもならない事が明確に示された出力である必要がある。はっちゃけ、「だれそれに連絡して下さい。」という表示が期待される。

・・・ぐだぐだ考えてきたけれど、結局、そういう事になると思う。YakiBikiでは基本、IDX/DAO系のファイル入出力でのPHP関数がこける・ファイルフォーマットが違う時とかが、後者に分類され、その他は基本全部前者になる。

・・・そんな感じ、かな。

*1:アプリによっては、重複値や0件系が開発者を呼ぶ必要があるエラーに分類されることもあるだろう。分け方はアプリに依ると思う。