# 共通ドキュメント

## エラー処理

アプリケーションがコーディング上想定していないデータ、リソースなどの使用により発生する例外について。

### 概要

- 基本
- Window Forms アプリケーションでのエラー処理
- Web アプリケーションでのエラー処理
- エラーメッセージ、エラーログ内容の組み立て
- 設定
- 実装済みのErrorHandler(Windows Forms)
- 実装済みのErrorHandler(Web)
- 実装済みのErrorMessageBuilder
- 新しい表示機能の実装
- 新しいErrorMessageBuilderの実装

### 基本

プログラム上では例外を処理せず、共通のハンドラーで例外を採取してログ出力などを行う。ただし特定リソースを扱うプログラムでは例外発生時に必ず使用したリソースを解放する事。

### Window Forms アプリケーションでのエラー処理

#### 概念

- Application.ThreadException および AppDomain.UnhandledExceptionのハンドラを設定する。
- それぞれのハンドラでエラーログを出力する。
- 必要であれば管理者にメール通知などする。
- エラーメッセージを表示する。一般的にはException#Messageを表示するだけでよい。

#### 注意事項

メッセージダイアログ表示の際、アイコンは「情報」(白丸に"i")または「エラー」(赤丸に"!")を使用し、「警告」(黄色三角に"!")は使用しない。「警告」がWindowsに於いては「取り戻せない結果を引き起こす操作の前の注意」を表すため。

#### 実装

- CFW.Windows.ErrorHandler.ApplicationErrorHandlerの実装クラスを作成する
- Program#Main開始時に上記クラスのオブジェクトを生成し、初期設定する。

#### サンプル(Program.cs)

    static class Program
    {
            ///
            /// アプリケーションのメイン エントリ ポイントです。
            ///
            [STAThread]
            static void Main()
            {
                //エラーハンドラーの設定
                //ハンドラーを生成する。ここで生成しているのはApplicationErrorHandlerのデフォルト実装。
                //コンストラクタに渡すパラメータはアプリケーション名
                CFW.Windows.ErrorHandler.DefaultApplicationErrorHandler handler =
                	new CFW.Windows.ErrorHandler.DefaultApplicationErrorHandler("例外処理サンプル");
                //初期設定する。
                CFW.Windows.ErrorHandler.ApplicationErrorHandler.SetUp(
                    handler
                    );

            }
        }

既定ではCFW.Windows.ErrorHandler.ApplicationErrorHandlerがエラーイベントの捕捉、ログ出力までを実行する。メッセージ表示は抽象メソッドなので各実装クラスに定義する必要がある。

### Web アプリケーションでのエラー処理

#### 概念

- web.config/configuration/system.web/customErrorsにエラーページを設定し、エラーメッセージを表示できるようにする。
- global.asax/Application_Errorメソッド内部でエラーログを出力する。
- 必要であれば管理者にメール通知などする。
- asp.netがエラーページを表示する。
- 必要であればエラーページに詳細なエラーを表示できるようにする。また、前のページに戻る方法を提供する。

#### 実装

- web.config/configuration/system.web/customErrorsにエラーページを設定し、エラーメッセージを表示できるようにする。
- global.asax/Application_Errorメソッド内部でCFW.Windows.ErrorHandler.ApplicationErrorHandler#HandleError()を呼び出す。
- 必要であれば管理者にメール通知などする。
- 必要であればエラーページに詳細なエラーを表示できるようにする。また、前のページに戻る方法を提供する。

#### web.configの設定

    <system.web>
        <customErrors mode="On" defaultRedirect="error.htm"><!-- 以下のコードに含まれない場合のページ -->
          <error statusCode="404" redirect="404.htm"/><!-- ページが見つからない -->
          <error statusCode="500" redirect="500.htm"/><!-- 500エラー(一般的なエラー) -->
        </customErrors>
    </system.web>

#### global.asax/Application_Errorメソッド内部

    <script runat="server">

        void Application_Error(object sender, EventArgs e)
        {
        	//例外データを取得
            Exception ex = Server.GetLastError();
            //ハンドラー生成
            CFW.Web.ErrorHandler.ApplicationErrorHandler handler = new CFW.Web.ErrorHandler.ApplicationErrorHandler();
            //エラー処理(ログ出力)を実行
            handler.HandleError(ex);
        }
    </script>

### エラーメッセージ、エラーログ内容の組み立て、出力

エラーメッセージ、エラーログ内容の組み立てはCFW.ErrorHandler.ErrorMessageBuilderの実装クラスに定義し、CFW.ErrorHandler.ErrorMessageBuilderFactory#GetInstance()を使ってインスタンスを得る。

表示はErrorMessageBuilder#BuildMessag()の結果を表示する。ログ出力にはErrorMessageBuilder#WriteLog()を使用する。

#### CFW.ErrorHandler.ErrorMessageBuilderの実装

以下のメソッドを実装あるいはオーバーライドする。

##### 実装するメソッド

BuildMessage | 表示用メッセージを組み立てる。
BuildLogMessage | ログ出力用メッセージを組み立てる

##### 必要に応じてオーバーライドするメソッド

WriteLog | ログ出力本体。通常はBuildLogMessage()の結果を全てのログ出力に出力する。
BuildMessageAsXmlNode | エラー内容をXmlNodeに組み立てる。主にSOAPメッセージ用。必要な要素は exception ,exception/type,exception/message,exception/stackTrace,exception/currentUser。その他は必要に応じて追加する。

#### メッセージ組み立てのマッピング

既定では以下のルールでErrorMessageBuilder実装クラスを得る。

- 元の例外クラス名+"MessgeBuilder"の名前を持つクラス
- "CFW.ErrorHandler." + 元の例外クラスの基本名 +"MessgeBuilder"の名前を持つクラス
- "CFW.ErrorHandler.DefaultErrorMessageBuilder"

このルール外のマッピングはapp.config/configuration/errorHandlerセクションに定義する。

##### サンプル(errorHandlerセクション)

    <configuration>
    <configSections>
        <!-- エラーハンドラー設定セクション定義 -->
        <section name="errorHandler" type="CFW.Config.ErrorHandlerConfigSettingSection,CFW" allowLocation="true" allowDefinition="Everywhere"/>
    </configSections>
    ...(snip)
    <!-- エラーハンドラー設定セクション -->
    <errorHandler>
        <!-- SQLサーバーの例外処理
        CFW.ErrorHandler.SqlExceptionMessageBuilder が処理する -->
        <add exceptionName="System.Data.SqlClient.SqlException"
            handler="CFW.ErrorHandler.SqlExceptionMessageBuilder,CFW" />
        <!-- テスト用
        CFW.Common.Test.ErrorHandler.NullPointerExceptionMessageBuilderが処理する
        -->
        <add exceptionName="CFW.Common.Test.ErrorHandler.NullPointerException"
            handler="CFW.Common.Test.ErrorHandler.NullPointerExceptionMessageBuilder,CFW.Common.Test" />
      </errorHandler>
    ...(snip)
    </configuration>

### 実装済みのErrorHandler(Windows Forms)

現在実装済みのErrorHandler(Windows Forms)は以下のとおり

ログ出力はベースクラス内に実装されている。

CFW.Windows.ErrorHandler.DefaultApplicationErrorHandler | 例外メッセージをメッセージボックス(エラー)に表示する。タイトルは構築時に指定したアプリケーション名か、exeの名称。メッセージの先頭行はMessage.Resource.dll/common/EXCEPTION_DEFAULT_MESSAGEを使用する。その他メッセージは例外クラスのMessageを表示する。StackTraceは表示しない。

### 実装済みのErrorHandler(Web)

現在実装済みのErrorHandler(Web)は以下のとおり

CFW.Web.ErrorHandler.ApplicationErrorHandler | ログ出力実行のみ。ログ出力にメール送信を実装しておけばメール送信可能

### 実装済みのErrorMessageBuilder

現在実装済みのErrorMessageBuilderは以下のとおり

CFW.ErrorHandler.DefaultErrorMessageBuilder | Exceptin.Message、StackTraceをログに出力する
CFW.ErrorHandler.SqlExceptionMessageBuilder | SQL例外のメッセージを出力する。内部エラーが存在する場合はすべてのエラーについて同様の処理を行う。
CFW.ErrorHandler.InvalidCastExceptionMessageBuilder | キャストエラー用(元はサンプルとして実装。)
CFW.ErrorHandler.FormatExceptionMessageBuilder | 書式化エラー用(元はサンプルとして実装。)
CFW.Database.ConnectionExceptionMessageBuilder | データベース接続例外のメッセージを出力する。実行時のコマンド内容も出力する