【问题标题】:Losing original stack trace in exception handling在异常处理中丢失原始堆栈跟踪
【发布时间】:2021-09-27 21:53:10
【问题描述】:

我正在尝试正确处理异常,所以我一直在试验这段代码:

 class MainClass
    {
        private static Logger logger = new Logger();

        public static void Main(string[] args)
        {

            try
            {
                Method1("");
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }
        }

        private static void Method1(string text)
        {
            try
            {
                Method2(text);
            }
            catch (Exception ex)
            {
                logger.Write(ex);
                throw ex;
            }
            
        }

        private static void Method2(string text)
        {
            try
            {
                Console.WriteLine(text[0]);
            }
            catch (Exception ex)
            {
                logger.Write(ex);
                throw;
            }
        }
    }

我注意到在Method2中记录的异常,它表明在try块中抛出了错误:"Console.WriteLine(text[0])"

System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at ExceptionHandlingTest.MainClass.Method2 (System.String text) [0x00002] in /ExceptionHandlingTest/Program.cs:40

但是在Method1记录的异常中,只显示在catch块中被抛出:throw;:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at ExceptionHandlingTest.MainClass.Method2 (System.String text) [0x00020] in /ExceptionHandlingTest/Program.cs:45 
  at ExceptionHandlingTest.MainClass.Method1 (System.String text) [0x00002] in //ExceptionHandlingTest/Program.cs:26 

我在这里做错了什么,还是它应该工作的方式?当我进入 Method1 时,InnerException 为 null。

我看到如果我从 Method2 中删除 try/catch,Method1 中的异常会在 Console.WriteLine 中出现我所期望的错误。我想这让我想知道:我如何确定在哪里/何时处理异常?似乎越早越好。

【问题讨论】:

  • 是的,阅读important box
  • 这就是我感到困惑的地方,因为在 Method2 中我只是使用 throw; 而在 Method1 中在执行 throw ex; 之前立即记录异常

标签: c# exception


【解决方案1】:

这几乎可以按预期工作。解释如下:

  • Method2Console.WriteLine(text[0]); 处使用堆栈跟踪记录异常:

    at [...].Method2(String text) in [...]:line 40
    
  • Method1throw 处记录带有堆栈跟踪的异常,该异常位于Method2catch 块中。然后,下一个堆栈帧在Method1 中的Method2(text); 调用处(堆栈跟踪被保留,因为您使用了throw,而不是throw ex):

    at [...].Method2(String text) in [...]:line 45
    at [...].Method1(String text) in [...]:line 26
    
  • Main 中,您没有记录异常;您只是在显示.Message 属性,该属性隐藏您正在发生的事情。如果您记录该异常并检查其跟踪跟踪,您会发现它从throw ex 开始,然后下一帧在对Method1(""); 的调用处。换句话说,缺少堆栈帧:

    at [...].Method1(String text) in [...]:line 31
    at [...].Main(String[] args) in [...]:line 10
    

    如果将throw ex 更改为throw 并记录在Main 中捕获的异常,则会保留第一个堆栈帧:

    at [...].Method2(String text) in [...]:line 45
    at [...].Method1(String text) in [...]:line 31
    at [...].Main(String[] args) in [...]:line 10
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-22
    • 2019-05-04
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 2017-05-08
    • 2011-01-05
    • 2015-07-30
    相关资源
    最近更新 更多