Skip to content

OTR_ExceptionHandling

nishi_74322014 edited this page Oct 27, 2026 · 1 revision

例外処理方式

概要

Open 棟梁に組み込まれた例外処理の基本方針と、API の使い方を説明する。

  • 例外の型(業務例外・システム例外・その他)ごとに、処理フローがフレームワーク側で設計されている。
  • 業務プログラムでは、原則として try ~ catch を書かない。
  • 業務例外はリスローされず、正常系の戻り値(ErrorFlag = true)に変換される。一般的な .NET の作法と逆なので注意する。

詳細

処理フロー

プログラムの最下層で例外がスローされると、次の流れで例外が伝播し、最上位層に伝わる。

クラス構造と例外の伝播

例外処理の処理フロー

例外の型

名前空間は Touryo.Infrastructure.Framework.Exceptions。

例外の種類の概要図

型 クラス 用途 業務の続行
業務例外 BusinessApplicationException リトライ可能なエラー(入力チェック、0 件、楽観排他の失敗、キー重複、デッドロック、ロックタイムアウト など) 可能。元の画面などに戻って続行
システム例外 BusinessSystemException アプリで原因を明確にできるが、リトライ不可能・させたくないエラー(システム閉塞、業務的なデータ不整合 など) 不可能。汎用エラー画面へ
フレームワーク例外 FrameworkException フレームワークが検出したエラー 不可能
その他 Exception 一般 バグや環境上の問題による想定外の例外(ランタイム・エラー) 不可能。原因の調査が必要
  • 迷ったら「利用者がやり直せば成功しうるか」で判断する。しうるなら業務例外、しえないならシステム例外。
  • ユーザ定義エラー用の例外の型を追加しない。 エラーの種類は messageID で識別する。

コンストラクタとプロパティ

// 業務例外:(messageID, message, information)
throw new BusinessApplicationException("E0001", "入力値が不正です。", "項目:数量");

// システム例外:(messageID, message)
throw new BusinessSystemException("S0001", "システムは閉塞中です。");
  • プロパティ messageID は小文字始まり(MessageID ではコンパイルが通らない)。
  • Information は BusinessApplicationException だけが持つ。

B 層での自動処理

B 層(BaseLogic.DoBusinessLogic)が、例外の型ごとに次を行う。業務コード側で書く必要はない。

スローした型 B 層の処理 呼び出し側(P 層)への到達形
業務例外 ロールバック、DB 切断、終了処理(アクセス・ログ等) 正常系の戻り値(ErrorFlag = true、ErrorMessageID、ErrorMessage、ErrorInfo)
システム例外 ロールバック、DB 切断、終了処理 システム例外がそのまま届く
その他 ロールバック、DB 切断、終了処理。リスローするかは親クラス2 の UOC_ABEND 次第 既定のテンプレートではそのまま届く

業務例外

システム例外、その他の例外

// 呼び出し側:業務例外は catch ではなく ErrorFlag で検知する
MyReturnValue rv = (MyReturnValue)layerB.DoBusinessLogic(pv);
if (rv.ErrorFlag)
{
    // rv.ErrorMessageID / rv.ErrorMessage を画面に表示し、業務を続行する
}
  • 呼び出し側で業務例外を catch しない(飛んでこない)。
  • B 層で業務例外を自分で catch しない(フレームワークの変換が働かなくなる)。
  • 2 層 C/S(Windows Forms、BaseLogic2CS)では、業務例外のときロールバックせず、そのまま継続する。

例外の振替

D 層でのキー重複・コマンド・タイムアウトなどは、データ・プロバイダの例外(=その他の例外)として返る。
親クラス2(MyFcBaseLogic)の UOC_ABEND で、これを業務例外に振り替えると、
P 層に正常系の戻り値として返り、元の画面に戻ってリトライさせられる。

例外の振替処理方式

  • その他の例外 → 業務例外
  • その他の例外 → システム例外

親クラス2 はプロジェクトの纏め者が実装する。業務開発者は振替の結果(ErrorFlag)を受け取るだけである。

メッセージとログ

型 画面 ログ(既定テンプレート)
業務例外 メッセージ・エリア(元の画面で続行) ACCESS ロガーにワーニング
システム例外 汎用メッセージ・エリアなど ACCESS ロガーにエラー
その他 汎用エラー画面(業務停止) ACCESS ロガーにエラー
  • messageID に対応するメッセージの雛形をリソースに定義し、個別の値を埋め込む方式も採れる(例:「{0}」に「{1}」権限がありません)。
  • ログ出力の詳細はログ出力方式 (log4net)を参照。

P 層フレームワークを使わない場合

UI スレッドの未処理例外をまとめてハンドルするイベントを使う。

イベント 対象
Application.ThreadException Windows Forms の UI スレッド
Application.DispatcherUnhandledException WPF の UI スレッド
AppDomain.CurrentDomain.UnhandledException すべての未処理例外(処理済みにはできない)
AppDomain.CurrentDomain.FirstChanceException ファーストチャンス例外(処理済みにはできない)
TaskScheduler.UnobservedTaskException バックグラウンド・タスクの未監視例外(処理済みにできる)

コーディング・エージェントに任せる場合

  • スキル opentouryo-exception を使わせる。B 層・D 層・P 層のどのコードでも、例外を扱うなら参照させる。
  • エージェントは一般的な .NET の作法で try ~ catch を書きがちなので、レビューでは「業務例外を catch していないか」「型を増やしていないか」を見る。

参考


Tags: 再構築

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki
開発基盤部会 Wiki

移行管理: DONE / TODO

Clone this wiki locally