例外の処理について
プログラムを書く上では必要らしい例外処理。
まぁ、人間ミスはかならずあるものなので、いざというときにエラー発生箇所を掴むための保険的なところなのでしょうか。
ということで、色々調べては見ましたが、結局こう書いておけばいいという一般的な記載はなく、あるところでは例外処理は無くていいという記述も合ったような気がします。
そりゃ、例外が出るはずがない処理にわざわざいれる必要なんてないですもんね。それに、目的によって書き方なんていくらでもあると言いますから。
とりあえず、VB.Netですが、使い方等いろいろやってきて、備忘録として書きます。
これも一つの例としてとうことで。
プロジェクトは何でもいいですが、適当にWindowsFormでボタンを設置。
まずはメインのソース。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
Imports System.Diagnostics Public Class Form1 Private st As StackTrace = Nothing Private sss As Integer = 0 Private ddd As Integer = 0 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Dim ggg As Integer = sss \ ddd Try 'Dim ggg As Integer = sss \ ddd aaa() MsgBox("aaaaaaaaa") Catch ex As Exception st = New System.Diagnostics.StackTrace(ex, True) MsgBox(ex.TargetSite.DeclaringType.Name + ":" + ex.TargetSite.Name + ":" + st.GetFrame(0).GetFileLineNumber()) End Try End Sub Private Sub aaa() 'Dim ggg As Integer = sss \ ddd Try bbb() 'Class1.fff() Catch ex As Exception Throw End Try End Sub Private Sub bbb() 'Dim ggg As Integer = sss \ ddd Try ccc() Catch ex As Exception Throw End Try End Sub Private Sub ccc() Dim ggg As Integer = sss \ ddd Try Catch ex As Exception End Try End Sub End Class |
あとは別クラスでも検証用に作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Public Class Class1 Private st As StackTrace = Nothing Private sss As Integer = 0 Private ddd As Integer = 0 Public Shared Sub fff() Dim class1 As New Class1 Dim ggg As Integer = class1.sss \ class1.ddd Try Catch ex As Exception End Try End Sub End Class |
関数や変数名が適当なのは気にしないでください。
ここで例外が出るところは変数「ggg」で、出現エラーはゼロ除算「System.DivideByZeroException」になります。
検証のためにそれぞれの関数に仕込んでいます。
動かしてみる
上記のメソッドを動かしてみるとこうなります。
エラーメッセージはそれこそ個人の自由ですが、今回は「クラス名:メソッド名:エラー行数」としています。
考察みたいなもの
まず、このプログラムにおける例外処理の決め事として、最終的なエラーメッセージ表示はボタンクリックイベントのメソッドで表示するということ。
ネストしたものは基本Throwして、上のメソッドに投げることを前提としています。
上記のイベントメソッドの中では「aaa()→bbb()→ccc()」と呼び出し、 ccc() の中のTry…Catch外で例外を発生させます。
結果として、ccc() のエラーがbbb()のCatchに入り、それがThrowされて、 さらにaaa()にもThrowされて、エラー表示されます。そして、その後のMsgBoxも表示されません。
ちなみに下記のようにすると。
1 2 3 4 5 6 7 |
Private Sub ccc() Try Dim ggg As Integer = sss \ ddd Catch ex As Exception Throw End Try End Sub |
ccc()の中の Try…Catch にエラー発生のコードを入れるとThrowがエラー行として出てきます。
ということで、「最上位でエラーを取得するやり方をするのであればという前提で」以下まとめます。
- 最下層には Try…Catch は置かなくていい
- Try…Catch 外のエラーが上位のメソッドでCatchされる
- 別クラスでも同様
- 最上位でのCatchなので、それ以降の処理はされない(Finallyで後処理は必要)
あと、今回のプログラムとは違い、それぞれのメソッドで例外をキャッチしたい場合は、Throwのことは考えなくていいかもしれません。
その代わり、例外メソッド以降の処理は続くのでそれでもいいプログラムならOKというところでしょうか。
これ、常識なんですかね。
この使い方で合っているのだろうか、相変わらず自信がないです…。
コメント