「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>アプリケーション設計のポイント]] *目次 [#b1b12edc] #contents *概要 [#pf4a927d] ”Open棟梁”に組み込まれた例外処理の基本方針を説明する。 *例外処理の処理フロー [#bae9594d] -例外処理の処理フローを、コラボレーション図、シーケンス図を使用して示す。 -例外処理の処理フローは、プログラムの最下層で例外がスローされた場合、~ 次の流れで例外が伝播し、最上位層に伝わるようになっている。 -フレームワークで用意した「例外の型」毎に、処理フローが個別に設計されている。 -なお、2層C/Sの例外処理の処理フローでは、「業務例外」の場合に、~ トランザクションのロールバック & 接続切断をしない(そのまま継続)。 **コラボレーション図 [#b4aab71e] #ref(ModuleAndExceptionPropagation.png,left,nowrap,クラス構造と例外の伝播) **シーケンス図 [#e427101f] #ref(ExceptionSequence.png,left,nowrap,例外処理の処理フロー) *例外の種類 [#va9dc24d] **概要 [#j5fa1baf] #ref(SummaryOfExceptionType.png,left,nowrap,例外の種類の概要図) **例外の型名 [#laa21711] ***業務例外 [#s1d87ff0] 業務的なエラーを通知するための例外 ***システム例外 [#ua602d39] 環境上の問題などで発生する例外であるが、アプリケーションに於いて原因を明確にできるもの。 ***その他、一般的な例外 [#ydc9bed7] バグや環境上の問題で発生する想定外の例外(ランタイム エラー)。別途、発生原因の調査が必要。 **例外の業務続行の可・不可 [#j3817819] ***業務例外 [#t7b9a154] -業務続行可能 -元の画面に戻るか、任意の業務画面まで戻るなどして業務続行。 ***システム例外 [#u7d1fbce] -業務続行不可能 -汎用エラー画面に遷移して業務を停止する(か、ユーザに確認する)。 ***その他、一般的な例外 [#x38d0db3] -業務続行不可能 -汎用エラー画面に遷移して業務を停止する(か、ユーザに確認する)。 *例外の種類と、ハンドリングの説明 [#q2bdf5f0] |項番|例外の種類|ハンドリングの説明|h |1|業務例外|業務続行可能なエラー用の例外をスローしたり、ハンドルしたりする。&br;&br;例えば、以下に列挙した、リトライ可能なエラーは、「業務例外」型を使用して例外をスローし業務を続行する。&br;・関連チェック エラー&br;・更新件数0件(タイムスタンプ アンマッチ)&br;・追加時のキー重複&br;・デッドロック&br;・ロック・タイムアウト&br;・コマンド・タイムアウト&br;・, etc.| |2|システム例外|業務続行不可能なエラー用の例外をスローしたり、ハンドルしたりする。&br;&br;例えば、以下に列挙した、アプリケーションで検出したが、リトライ不可能 or リトライさせたくないエラーは、&br;「システム例外」の型を使用して例外をスローし(基本的に)業務を停止する。&br;・リトライ不可能な、業務的なデータ不整合などのエラー| |3|その他、一般的な例外|ランタイム エラーなど、UPで特別に検知しない例外。この例外が発生した後、&br;例外の振替など特別な措置を取らない限りリトライ不可能であり、(基本的に)業務を停止する。&br;&br;ここでのリトライは、「UIからのリトライ」、「プログラム内でのリトライ」の両方を指すが、いずれもトランザクション・ロールバック後のリトライを指す。&br;(プログラム・レベルのリトライや、同一トランザクション内のリトライは、リトライ回数・間隔を調整したとしても有用になり難いので)| **業務例外 [#c4d020af] #ref(BusinessApplicationException.png,left,nowrap,業務例外) ***B層で発生 [#wba10a2f] B層で「業務例外」をスローすると以下の処理が実行される。 -トランザクションをロールバック、DBの切断。 -終了処理(例外処理)が呼び出される(アクセス ログ出力など) -P層のイベント処理に正常系の戻り値を戻す(ErrorFlagがtrue)。 ***P層で発生 [#n19aea51] P層で「業務例外」をスローすると以下の処理が実行される。 -終了処理(例外処理)が呼び出される(アクセス ログ出力など) -共通エリアにメッセージ表示 **システム例外、その他一般的な例外 [#c4d020af] #ref(BusinessSystemException_ElseException.png,left,nowrap,システム例外、その他の例外) ***B層で発生 [#wba10a2f] B層で「システム例外」、「その他一般的な例外」をスローすると以下の処理が実行される。 -トランザクションをロールバック、DBの切断。 -終了処理(例外処理)が呼び出される(アクセス ログ出力など) -P層にそのまま例外を返す(リスローされる)。 ***P層で発生 [#n19aea51] P層で「システム例外」、「その他一般的な例外」をスローすると以下の処理が実行される。 -終了処理(例外処理)が呼び出される(アクセス ログ出力など) -汎用エラー画面を呼び出し、メッセージを表示する。 -業務を停止する。 **例外の振替処理方式 [#t1b2b0ba] 例えば、D層でレコード追加時のキー重複エラー、コマンド タイムアウトなどが発生した場合、~ これはデータ プロバイダの提供する例外、すなわち、「その他、一般的な例外」として返される。 これをB層のルートの例外処理で「業務例外」に振り替えれば、P層に正常系の戻り値として例外情報が戻るため、~ これから、元の画面に戻るか、業務開始時点の画面まで戻るなどの処理を個別に実装して、~ 追加時のキー重複、デッドロック、ロックタイムアウト、コマンドタイムアウト.etcのリトライが可能である。 ”Open棟梁”の「業務コード親クラス2」のカスタム例外処理部に -「その他、一般的な例外」 → 「業務例外」 -「その他、一般的な例外」 → 「システム例外」 などの例外の振替処理を実装できる。 下図は、「その他、一般的な例外」 → 「業務例外」へ例外を振り替える例外処理方式である。 #ref(ChangeException.png,left,nowrap,例外の振替処理方式) *例外処理の基本方針 [#xb6f58da] **例外のtry ~ catch [#qee70f28] -例外のtry ~ catchは、P層フレームワーク側で処理するため、業務プログラムではtry ~ catchしない。 -例外のtry ~ catchは、[[P層フレームワーク>#bae9594d]]側で処理するため、業務プログラムではtry ~ catchしない。 -P層フレームワーク的なモノを導入しないで実装する場合、 --Application.ThreadException~ UIスレッドで発生した未処理例外をまとめてハンドリング(Windows Forms) --Application.DispatcherUnhandledException~ UIスレッドで発生した未処理例外をまとめてハンドリング(WPF) >イベントのハンドラを併用する。 -他にも、以下のような例外処理用のイベントのハンドラが存在する。 --AppDomain.CurrentDomain.UnhandledException~ 全ての[[未処理例外>https://techinfoofmicrosofttech.osscons.jp/index.php?%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%83%BB%E3%83%80%E3%83%B3%E3%83%97#w7d8cfcf]]のイベントをハンドルする(処理済みにはできない)。 --AppDomain.CurrentDomain.FirstChanceException~ [[ファーストチャンス例外>https://techinfoofmicrosofttech.osscons.jp/index.php?%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%83%BB%E3%83%80%E3%83%B3%E3%83%97#vd71c433]]のイベントをハンドルする(処理済みにはできない、.NET 4.0以降)。 --TaskScheduler.UnobservedTaskException ---バックグラウンドで発生した未処理例外をUnhandledExceptionの前にハンドリングして処理済みにできる(.NET 4.0以降) ---App.configファイルのThrowUnobservedTaskExceptionsの設定次第で挙動が変わる。~ (trueに設定すると、.NET 4.5の動作を.NET 4.0と同じプログラムが終了する動作にできる) -参考 --WPF:例外をまとめてトラップするには?[C#/VB]:.NET TIPS - @IT~ https://www.atmarkit.co.jp/ait/articles/1512/16/news026.html --捕捉されなかった例外がスローされたことを知る - .NET Tips (VB.NET,C#...)~ https://dobon.net/vb/dotnet/programing/unhandledexception.html --https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Samples/WS_sample/WSClient_sample/WSClientWin_sample/Program.cs#L41 **エラー メッセージの設定と表示方針 [#h6682895] -ErrorMessageIDに対応するメッセージの雛形を任意の外部リソースに定義しても良い。 -メッセージの雛形に、String.Formatを使用して個別メッセージを組み込み、メッセージを作成する。~ ※ メッセージ例:「{0}」に、「{1}」権限がありません。 -その場合、個別メッセージは、「業務例外」をスローする前に設定する。 ***業務例外 [#te62af4d] -画面:汎用メッセージ・エリアなど -ログ:エラー ログではなく、ワーニング ログを出力する。 ***システム例外 [#p82ed189] -画面:汎用メッセージ・エリアなど -ログ:「システム例外」の例外情報をエラー ログに出力する。 ***その他、一般的な例外 [#lf107748] -画面:汎用エラー画面など -ログ:「その他、一般的な例外」の例外情報をエラー ログに出力する。 IP:202.246.252.109 TIME:"2021-06-11 (金) 11:21:02" REFERER:"https://opentouryo.osscons.jp/index.php?cmd=edit&page=%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%E6%96%B9%E5%BC%8F" USER_AGENT:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36"