業務エラーを「制御」せよ:VB.NETにおけるカスタム例外設計の極意
システム開発において、最も避けるべきは「エラーの曖昧さ」です。
ファイルが読み込めなかったのか? データベースの接続が切れたのか? それとも、ユーザーが在庫数にマイナス値を入力しただけなのか? これらをすべて `Exception` という雑多な箱に放り込んでいませんか?
もしあなたが、例外処理を「とりあえず `Catch Ex As Exception` で握りつぶしてログを吐く」ことだけで満足しているなら、今すぐその設計を捨ててください。真に堅牢な業務システムは、「システムが崩壊したのか(System Error)」と「業務ルールが守られなかったのか(Business Exception)」を明確に分離します。
今日は、VB.NETにおいて「保守性を劇的に向上させるカスタム例外の実装」という武器を授けます。
—
1. なぜ「例外」を分ける必要があるのか
多くの初学者が陥る罠は、すべてのエラーを一律に扱うことです。しかし、実務では以下の2つは明確に区別すべきです。
- システム例外 (Technical Exception): DB接続エラーやファイルアクセス権限など、プログラム側に起因する「異常」。これらは再試行や管理者の介入を要する。
- 業務例外 (Business Exception): 「在庫不足」「入力値不正」など、業務フロー上あり得る「想定内」の事象。これらはユーザーに正しい操作を促すメッセージとしてフィードバックすべき。
この区別を怠ると、ユーザーは「システムエラーが発生しました」という無機質な画面に怯え、開発者はログの海から針を探すようなデバッグを強いられることになります。
—
2. 実践:継承によるカスタム例外の作成
VB.NETでは、`Exception` クラスを継承して独自の例外を作るのが定石です。
”’
”’
Public Class BusinessLogicException
Inherits Exception
‘ ユーザーに表示すべきメッセージを保持させるのがポイント
Public Property UserMessage As String
Public Sub New(message As String, userMessage As String)
MyBase.New(message)
Me.UserMessage = userMessage
End Sub
‘ 必要に応じて、エラーコード等を持たせるのも良い設計です
End Class
このように設計することで、`Catch` ブロックで「これはシステムエラーか? それとも業務エラーか?」を明確に分岐できます。
—
3. プロダクションコードでの実装例
ファイル処理を行うサービス層を例に見てみましょう。
Public Sub ProcessFile(filePath As String)
‘ 1. ファイルの存在確認
If Not System.IO.File.Exists(filePath) Then
‘ これは「業務上の想定内エラー」
Throw New BusinessLogicException(“ファイルが存在しません”, “指定されたファイルが見つかりません。パスを確認してください。”)
End If
Try
‘ 2. ファイル読み込み
Dim content = System.IO.File.ReadAllText(filePath)
‘ … 処理 …
Catch ex As System.IO.IOException
‘ これは「システムエラー」
‘ ログには詳細を記録し、上位には例外を再スロー(もしくはラップ)する
Throw New ApplicationException(“ファイル読み込みに失敗しました”, ex)
End Try
End Sub
—
4. 上位層(呼び出し側)での美しいハンドリング
UI層やコントローラー層では、以下のように例外の種類によって処理を分岐させます。これが「堅牢な設計」の正体です。
Try
Service.ProcessFile(“data.txt”)
Catch ex As BusinessLogicException
‘ 業務エラーなら、ユーザーに優しく通知
MessageBox.Show(ex.UserMessage, “確認”, MessageBoxButtons.OK, MessageBoxIcon.Warning)
Catch ex As Exception
‘ システムエラーなら、ログ出力と管理者への報告
Logger.Error(ex)
MessageBox.Show(“予期せぬエラーが発生しました。システム管理者に連絡してください。”, “エラー”, MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
—
5. 業務自動化エンジニアとしての提言
この設計を採用することで、あなたのコードは以下のように変わります。
1. デバッグコストの激減: ログを見た瞬間に「これはコードの問題か、ユーザーの問題か」が判別できる。
2. UI/UXの向上: ユーザーは「何が間違っていたのか」を具体的に知ることができる。
3. 保守性の維持: 将来的に新しい業務ルールが増えても、`BusinessLogicException` を継承したクラスを増やすだけで、処理構造を壊さずに拡張できる。
最後に
コードを「動かす」のは誰にでもできます。しかし、「エラーが起きた瞬間に、次に何をすべきかを正確に指示するコード」を書ける者は稀です。
例外処理とは、プログラムの敗北処理ではありません。システムが健全に生き残るための「防衛戦術」です。ぜひ、今日からあなたのVB.NETプロジェクトにこの設計思想を取り入れてみてください。
あなたの書くコードが、誰かの業務を救い、そして何より、あなた自身の未来のデバッグ時間を救うことを願っています。
