大尾巴狼

所谓大尾巴狼,就是装腔作势。

为什么有时不能正确定位到异常的发生位置?


在我们定位异常发生位置的时候,一般都能得到正确的异常信息(Exception.Message)。
但是当根据调用堆栈来定位异常发生点的时候,却往往得不到正确的位置,即正确的调用堆栈。
这与再次抛出异常的方式有关,请看下面的程序和输出结果。

在foo_ABC中捕获、处理、并重新抛出异常。在Main函数中最终来处理异常,获得详细的异常信息。
当使用 throw ex 后,在异常的调用堆栈里就不是正确正确的异常发生位置。
如果有源代码则可以顺着继续找,如果没有的话,则不好正确定位异常的发起的根源。

结论:
异常的调用堆栈,是以发生异常或者throw ex为起点的,当使用throw ex时会覆盖掉发生异常时产生的调用堆栈。
所以, foo_A()函数里抛出异常的方式要慎用!


  1 using System;
  2 
  3 namespace ConsoleApplication18
  4 {
  5     /// <summary>
  6     /// Summary description for Class1.
  7     /// </summary>
  8     class Class1
  9     {
 10         /// <summary>
 11         /// The main entry point for the application.
 12         /// </summary>
 13         [STAThread]
 14         static void Main(string[] args)
 15         {
 16             try
 17             {
 18                 foo_A();
 19             }
 20             catch(Exception ex)
 21             {
 22                 Console.WriteLine("=================Main");
 23                 Console.WriteLine(ex.ToString());
 24                 Console.WriteLine("");Console.WriteLine("");
 25             }
 26 
 27             try
 28             {
 29                 foo_B();
 30             }
 31             catch(Exception ex)
 32             {
 33                 Console.WriteLine("=================Main");
 34                 Console.WriteLine(ex.ToString());
 35                 Console.WriteLine("");Console.WriteLine("");
 36             }
 37 
 38             try
 39             {
 40                 foo_C();
 41             }
 42             catch(Exception ex)
 43             {
 44                 Console.WriteLine("=================Main");
 45                 Console.WriteLine(ex.ToString());
 46                 Console.WriteLine("");Console.WriteLine("");
 47             }
 48 
 49             int i = Console.Read();
 50         }
 51 
 52         private static void foo()
 53         {
 54             throw new Exception("happend in foo");
 55         }
 56 
 57         private static void foo1()
 58         {
 59             foo();
 60         }
 61 
 62         private static void foo_A()
 63         {
 64             try
 65             {
 66                 foo1();
 67             }
 68             catch(Exception ex)
 69             {
 70                 Console.WriteLine("=================foo_A   throw ex;");
 71                 Console.WriteLine(ex.ToString());
 72                 
 73                 throw ex;
 74 
 75             }
 76         }
 77 
 78         private static void foo_B()
 79         {
 80             try
 81             {
 82                 foo1();
 83             }
 84             catch(Exception ex)
 85             {
 86                 Console.WriteLine("=================foo_B  throw");
 87                 Console.WriteLine(ex.ToString());
 88                 
 89                 throw;
 90             }
 91         }
 92 
 93         private static void foo_C()
 94         {
 95             try
 96             {
 97                 foo1();
 98             }
 99             catch(Exception ex)
100             {
101                 Console.WriteLine("=================foo_C  throw new Exception(\"throw again by new\",ex)");
102                 Console.WriteLine(ex.ToString());
103                 
104                 throw new Exception("throw again by new",ex);
105             }
106         }
107     }
108 }

输出结果:

=================foo_A   throw ex;

System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo() in e:\my documents\visual studio project

s\consoleapplication18\class1.cs:line 54

   at ConsoleApplication18.Class1.foo1() in e:\my documents\visual studio projec

ts\consoleapplication18\class1.cs:line 59

   at ConsoleApplication18.Class1.foo_A() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 66

=================Main

System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo_A() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 73

   at ConsoleApplication18.Class1.Main(String[] args) in e:\my documents\visual

studio projects\consoleapplication18\class1.cs:line 18

 

 

=================foo_B  throw

System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo() in e:\my documents\visual studio project

s\consoleapplication18\class1.cs:line 54

   at ConsoleApplication18.Class1.foo1() in e:\my documents\visual studio projec

ts\consoleapplication18\class1.cs:line 59

   at ConsoleApplication18.Class1.foo_B() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 82

=================Main

System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo() in e:\my documents\visual studio project

s\consoleapplication18\class1.cs:line 54

   at ConsoleApplication18.Class1.foo1() in e:\my documents\visual studio projec

ts\consoleapplication18\class1.cs:line 59

   at ConsoleApplication18.Class1.foo_B() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 89

   at ConsoleApplication18.Class1.Main(String[] args) in e:\my documents\visual

studio projects\consoleapplication18\class1.cs:line 29

 

 

=================foo_C  throw new Exception("throw again by new",ex)

System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo() in e:\my documents\visual studio project

s\consoleapplication18\class1.cs:line 54

   at ConsoleApplication18.Class1.foo1() in e:\my documents\visual studio projec

ts\consoleapplication18\class1.cs:line 59

   at ConsoleApplication18.Class1.foo_C() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 97

=================Main

System.Exception: throw again by new ---> System.Exception: happend in foo

   at ConsoleApplication18.Class1.foo() in e:\my documents\visual studio project

s\consoleapplication18\class1.cs:line 54

   at ConsoleApplication18.Class1.foo1() in e:\my documents\visual studio projec

ts\consoleapplication18\class1.cs:line 59

   at ConsoleApplication18.Class1.foo_C() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 97

   --- End of inner exception stack trace ---

   at ConsoleApplication18.Class1.foo_C() in e:\my documents\visual studio proje

cts\consoleapplication18\class1.cs:line 104

   at ConsoleApplication18.Class1.Main(String[] args) in e:\my documents\visual

studio projects\consoleapplication18\class1.cs:line 40


 





 

posted on 2007-06-30 14:26  大尾巴狼  阅读(3142)  评论(8编辑  收藏  举报

导航