2011年1月17日月曜日

【VB.NET】ExitException

今回はエラー処理のお話です。


  1. Public Function A()  
  2.         Try  
  3.             If Not AA() Then  
  4.                 Return False  
  5.             End If  
  6.   
  7.             ' なんらかの処理  
  8.   
  9.         Catch ex As Exception  
  10.             MessageBox.Show("A にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  11.             Return False  
  12.         End Try  
  13.   
  14.         Return True  
  15.     End Function  
  16.   
  17.     Public Function AA() As Boolean  
  18.         Try  
  19.             If Not AAA() Then  
  20.                 Return False  
  21.             End If  
  22.   
  23.             ' なんらかの処理  
  24.   
  25.         Catch ex As Exception  
  26.             MessageBox.Show("AA にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  27.             Return False  
  28.         End Try  
  29.   
  30.         Return True  
  31.     End Function  
  32.   
  33.     Public Function AAA() As Boolean  
  34.         Try  
  35.   
  36.             ' なんらかの処理  
  37.   
  38.         Catch ex As Exception  
  39.             MessageBox.Show("AAA にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  40.             Return False  
  41.         End Try  
  42.   
  43.         Return True  
  44.     End Function  
つまりこんな感じの処理です。
  1. A関数処理  
  2.  AA関数処理  
  3.   AAA関数処理  
  4.  AA関数処理  
  5. A関数処理  
AAA関数でエラーが発生した場合、AAの後の処理は行ってはいけないわけです。 行わないように
  1. If Not AAA() Then  
  2.                 Return False  
  3.             End If  
と記述し、エラーの場合は即座に親関数に戻しています。

私はこの記述が面倒くさいと考えました。

面倒な理由は

・ If Not ~ という記述を毎回行わないといけない。
・ エラーメッセージの記述が面倒。メンテナンスも面倒。


そこで考案した方法は、
  1. Public Class ExitException  
  2.         Inherits Exception  
  3.         Public Sub New(Optional ByVal ErrMsg As String = "エラーが発生しました。")  
  4.             MyBase.New(ErrMsg)  
  5.         End Sub  
  6.         Public Sub New(ByVal ErrMsg As StringByVal ex As Exception)  
  7.             MyBase.New(ErrMsg, ex)  
  8.         End Sub  
  9.     End Class  
  10.   
  11.     Public Function A()  
  12.         Try  
  13.             Call AA()  
  14.   
  15.             ' なんらかの処理  
  16.   
  17.         Catch ex As Exception  
  18.             ErrMsg(ex, "A にてエラーが発生しました。")  
  19.             Throw New ExitException  
  20.         End Try  
  21.   
  22.         Return True  
  23.     End Function  
  24.   
  25.     Public Function AA() As Boolean  
  26.         Try  
  27.             Call AAA()  
  28.   
  29.             ' なんらかの処理  
  30.   
  31.         Catch ex As Exception  
  32.             ErrMsg(ex, "AA にてエラーが発生しました。")  
  33.             Throw New ExitException  
  34.         End Try  
  35.   
  36.         Return True  
  37.     End Function  
  38.   
  39.     Public Function AAA() As Boolean  
  40.         Try  
  41.   
  42.             ' なんらかの処理  
  43.   
  44.         Catch ex As Exception  
  45.             ErrMsg(ex, "AAA にてエラーが発生しました。")  
  46.             Throw New ExitException  
  47.         End Try  
  48.   
  49.         Return True  
  50.     End Function  
  51.   
  52.     Public Sub ErrMsg(ByVal ex As Exception, Optional ByVal Message As String = "")  
  53.         If TypeOf ex Is ExitException Then  
  54.             Exit Sub  
  55.         Else  
  56.             If Message = "" Then  
  57.                 ' メッセージを指定していない場合  
  58.                 Message = "不正なエラーが発生しました。"  
  59.   
  60.                 ' 実行関数名取得してメッセージに含める。これに関してはまた改めて・・  
  61.             End If  
  62.   
  63.             MessageBox.Show(Message, "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  64.   
  65.         End If  
  66.   
  67.     End Sub  
です。 まず、 if Not ~ の記述がなくなっています。

そして共通エラークラスとして ExitException というのが増えており、 ErrMsgという共通関数が増えています。

ExitException ・・・ 発生した場合、エラーメッセージを表示しないエラー。素通りのエラー。
ErrMsg     ・・・ エラーメッセージを表示する関数。ログ書き込みとかもここで実装していいかもしれません。
クラス化してログ書き込みパラメータとかにするともっといいかもしれませんね。

Throw New ExitException を実行するとエラーメッセージを出さずに親の関数にエラーを通知できると考えれば良いと思います。

また、ErrMsgなどで呼び出し元の実行関数名を取得することもできるので、エラーメッセージやログに活用することもできます。


とりあえず少し走り書きで書きましたが、ここまで。

 

0 件のコメント:

コメントを投稿