ASP.NETのC#環境で、発生した例外を同じメソッド内でキャッチして再スローした時のスタックトレース内容について

たぶんASPとかC#とか関係なくて.Net Frameworkの仕様だと思うんだけど。

  1: protected void Page_Load(object sender, EventArgs e)
  2: {
  3:     try
  4:     {
  5:         test();
  6:     }
  7:     catch (Exception ex)
  8:     {
  9:         throw;
 10:     }
 11: }
 12: private void test()
 13: {
 14:     throw new Exception("test error!");
 15: }

この場合のスタックトレース

 [Exception: test error!]
   test.test() in c:\cvs\test.aspx.cs:14
   test.Page_Load(Object sender, EventArgs e) in c:\cvs\test.aspx.cs:5
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15

9行目のthrow;throw ex;にするとスタックトレースの1行目が無くなって例外発生元の追跡が出来なくなる。ここまではMSDNの資料にあるとおり。

例外をキャッチして再スローする場合は、空の throw を使用してください。例外呼び出し履歴を保持するには、これが最善の方法です。

このソースの12行目からを次のように変更する。test()メソッド内で一度キャッチしてから再スローするように。

 12: private void test()
 13: {
 14:     try
 15:     {
 16:         throw new Exception("test error!");
 17:     }
 18:     catch (Exception ex)
 19:     {
 20:         throw;
 21:     }
 22: }

この場合のスタックトレース

 [Exception: test error!]
   test.test() in c:\cvs\test.aspx.cs:20
   test.Page_Load(Object sender, EventArgs e) in c:\cvs\test.aspx.cs:5
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15

1行目を見るとtest()メソッドで発生した所までは追跡できるけど、行番号が例外をキャッチして再スローしている20になっちゃいます。本当は例外発生元の16が出て欲しいのに。

try内に大量の処理がある場合はスタックトレースからこれ以上追跡できません。