【问题标题】:Exceptions: How can I get the most possible information?例外:我怎样才能获得尽可能多的信息?
【发布时间】:2013-01-12 01:22:16
【问题描述】:

我有一个企业应用程序,它会在发生异常信息时记录异常信息。该应用程序是 C# 和 C++.net 的组合。

我想在异常发生时尽可能多地获得信息。截至目前,我们只打印出消息和堆栈跟踪(在调试版本中提供行号,但不提供发布)。

任何错误日志的目标都是尽其所能(尽可能接近)指出错误。我很好奇我怎么能走得更远?我想要更多信息。

例如,我知道 NullReferenceExceptions 和 InvalidArguementExceptions 包含不同数量的信息,但我没有利用除“消息”字段之外的任何内容。

我最好的选择是使用反射并捕获所有公共成员并将它们打印出来吗?或者也许链接大量的类型检查和强制转换以干净地打印出来?作为一个约束,我的日志记录函数只需要接受一个异常类型的参数。

【问题讨论】:

  • 在异常对象上调用ToString() 通常足以满足我的需要。这给了我异常类型、消息和堆栈跟踪。
  • 这些东西都很有用,但是,我遇到了在非常大规模的算法中间出现空引用异常的问题。在这种情况下,nullreferencexception 包含引发异常的变量的数据类型,如果能获得该信息,那就太好了!
  • 我不关心当前的异常处理和恢复。现在我只是在尝试优化我们的异常记录器以包含更多信息。
  • 在记录异常时是否会循环记录内部异常,以便为您提供尽可能多的信息?
  • @James,不,我不知道。这是个好主意。

标签: c# .net exception logging reflection


【解决方案1】:

一般来说,答案是记录 ex.ToString()。通常,对象的 ToString 方法会显示对象希望您知道的内容。对于基 Exception 类,除了任何 InnerException 实例之外,还包括消息和堆栈跟踪。 Exception 的特定派生类可能会显示更多信息。

像 SqlException 这样的一些异常也会捕获附加信息(如存储过程名称和行号)。在这些情况下,将整个异常序列化并将其作为 XML 保存在日志数据库中会很有帮助。请注意,并非所有异常类都可以序列化,因此请准备好在 XML 部分上踢。

另外,如果您所做的只是记录异常,那么您可能需要重新抛出异常,以便更高级别有机会处理它。当然,这不适用于您已经处于“顶级”的情况。

【讨论】:

    【解决方案2】:

    试试这个:

    try 
    {
        //...
    }
    catch(Exception ex)
    {
        Messagebox.Show(ex.ToString());
    }
    

    它显示了很多信息,包括所有异常的异常类型消息堆栈跟踪(所有异常的InnerException例外情况)。

    MSDN 中的更多信息。

    【讨论】:

    • ex.ToString() 提供了非常多的信息除非有人在一个专门的类中覆盖了ToString 方法并且忘记在他的override 中提供所有信息。
    • 为什么投反对票? ex.ToString() 是获取异常希望您了解的所有信息的正确方法吗?
    【解决方案3】:
            private static string ErrorManager(Exception ex, bool ShowPopUp, bool CrashProgram)
        {
            string stack = ex.StackTrace;
            string source = ex.Source;
            string message = ex.Message;
            string LF = Environment.NewLine;
    
            string Error = $"A crash happen at {DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss.ff", CultureInfo.InvariantCulture)}{LF}" +
                           $"This is what crashed: {source}{LF}" +
                           $"This is the error message : {LF}{message}{LF + LF}" +
                           $"These are the last instructions executed before the crash : {LF}{stack}{LF + LF}";
    
            if (ex.InnerException != null)
            {
                Error += $"Inner Exception : {LF}{ex.InnerException.Message}";
            }
    
            if (ShowPopUp)
            {
                MessageBox.Show(Error, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
    
            if (CrashProgram)
            {
                throw new Exception(Error);
            }
            return Error.Trim();
        }
    

    【讨论】:

    • 为了得到一个有用的答案,这个反应需要扩展。解释为什么这是问题的答案。
    猜你喜欢
    • 2011-06-04
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    相关资源
    最近更新 更多