[.NET] 例外を Throw しなおすときは、 例外を付けてはいけない ( その2 )
Visual Studio のコード分析で警告される CA2200 "Rethrow to preserve stack details" についての、 続きです。 ( その1 は、 こちら )
実際にサンプルコードで説明していきます。
◆ 例外を出すメソッド ( 呼び出される側 )
Module Module2
Public Function Calc1(ByVal x As Integer, ByVal y As Integer) As Integer
Dim result As Integer = x / y '5行目
Return result
End Function
End Module
このメソッドに y = 0 を渡すと、 5行目で例外が発生します。
その例外が出た時に、 例外の発生元はここであるとすぐに分かるかどうかで、 デバッグの難易度が違ってくるでしょう。
このメソッドを呼び出すコードを何種類か示します。
着目すべき点は、 バグが発覚したとき ( 例外が出た時 ) に、 このメソッド Module2 の 5行目にたどりつけるかどうか、 です。
◆ 呼び出す側のメソッド・その1 ( Try ~ Catch 無し )
Public Class Class1
Public Shared Sub Method1()
Dim x As Integer
Dim y As Integer
Dim result As Integer
x = 10
result = Module2.Calc1(x, y) '10行目
End Sub
End Class
10行目で、 y に値を設定しないまま ( 0 のまま )、 上記の Module2.Calc1() メソッドを呼び出しています。
メイン関数から、 この Method1() を呼び出すと、 例外が発生し次のようなスタックトレースが報告されます。
OverflowException occured in Class1:
at ThrowVsThrowEx.Module2.Calc1(Int32 x, Int32 y) in E:\sample\ThrowVsThrowEx\ThrowVsThrowEx\Module2.vb:line 5
at ThrowVsThrowEx.Class1.Method1() in E:\sample\ThrowVsThrowEx\ThrowVsThrowEx\Class1.vb:line 10
at ThrowVsThrowEx.Module1.Main() in E:\sample\ThrowVsThrowEx\ThrowVsThrowEx\Module1.vb:line 5
問題の Module2 の5行目が、 きちんと報告されています。 呼び出す側の Class1 10行目も出ています。
◆ 呼び出す側のメソッド・その2 ( Catch して Throw Ex )
では、 Catch した上で、 その例外オブジェクトを指定して Throw する ( rethrow する ) と、 どうなるでしょう。
Public Class Class2
Public Shared Sub Method1()
Try
Dim x As Integer
Dim y As Integer
Dim result As Integer
x = 10
result = Module2.Calc1(x, y) '10行目
Catch ex As Exception
Throw ex '15行目
Finally
Console.WriteLine("* The Finally phrase was excuted in Class2")
End Try
End Sub
End Class
同じく、 メイン関数から呼び出した時の出力です。 ( Finally 句の出力も出ています。 )
* The Finally phrase was excuted in Class2
OverflowException occured in Class2:
at ThrowVsThrowEx.Class2.Method1() in E:\sample\ThrowVsThrowEx\ThrowVsThrowEx\Class2.vb:line 15
at ThrowVsThrowEx.Module1.Main() in E:\sample\ThrowVsThrowEx\ThrowVsThrowEx\Module1.vb:line 14
報告されているのは、 Throw ex している行だけです。 本当に例外を出している Module2 の 5行目は報告されていません。 ( これが、 MSDN Library に書いてある 「スタックトレースは現在のメソッドで再開され、 例外をスローした元のメソッドと現在のメソッドの間で呼び出されたメソッドの一覧は失われます。」 ということです。 )
このくらいシンプルなコードだと、 例外を出している場所の見当は付けられると思いますが、 もっと複雑なコードの場合はどうでしょう?
# その3 ( 最終回 ) へと続く… f(^^;
| 固定リンク
« [.NET] 例外を Throw しなおすときは、 例外を付けてはいけない ( その1 ) | トップページ | [.NET] 例外を Throw しなおすときは、 例外を付けてはいけない ( その3 ) »
「プログラミング」カテゴリの記事
- 【.NET / Win8.1 ストアアプリ】 HttpClient で TLS 1.1 / 1.2 に対応するには(2018.06.17)
- 【VS2017 15.7pv2】 XAML のランタイム ツールに 「ヒートマップ」 が増えた(2018.03.28)
- 【.NET Core】 プロジェクトを作ると 「project.assets.json が見つかりません」 エラー(2018.02.10)
- 【#UWP】 ビットマップの表示色を変える (Win2D.uwp 経由で Direct2D を使う)(2017.08.23)
- 【#UWP】 CompactOverlay モード: Picture in Picture というか、「最前面に表示」するウィンドウを作る(2017.08.16)
この記事へのコメントは終了しました。
コメント