【问题标题】:What is the best practice for capturing all inner exception details? [duplicate]捕获所有内部异常详细信息的最佳实践是什么? [复制]
【发布时间】:2013-08-31 14:44:42
【问题描述】:

记录完整异常详细信息(包括所有可能的内部异常)的最佳做法是什么?

目前,我使用以下代码:

try
{
    //some code that throws an exception
}
catch(Exception ex)
{
    do
    {
        Console.WriteLine(ex.Message+ex.StackTrace);
        ex=ex.InnerException;
    }while(ex!=null)
}

是否存在此代码可能失败的情况?

【问题讨论】:

  • 是的,您可能还想处理AggregateException,因为他们有一个InnerExceptions 属性,否则您会错过。
  • 您的记录器没有处理整个异常,还是您正在编写记录器?
  • 我假设您实际上使用了一些实用程序(第三方记录器或您自己的类/实现),因此您不会在需要尝试/捕获/记录的任何地方重复记录代码本身?此外,我个人对其进行了更新,因此它为每个连续的内部异常增加了初始选项卡缩进(或者您可以使用其他机制),因此当我阅读日志时,我可以区分 InnerException 父/子关系,而不仅仅是获得一个平面列表异常并试图找出一个停止和另一个开始的地方。编辑:并且我在它前面加上“INNER-EXCEPTION:”
  • @MatthewWatson 直到现在我才知道 AggregateException!谢谢
  • 使用 ex.ToString() 会是更好的做法。

标签: c# .net exception exception-handling


【解决方案1】:

您是否尝试过仅使用ex.ToString()?它提供了您需要诊断的大部分(如果不是全部)数据 - 包括消息详细信息、堆栈跟踪和内部异常:

来自MSDN:

ToString 返回当前异常的表示形式,即 旨在为人类所理解。异常包含在哪里 文化敏感数据,由 ToString 返回的字符串表示 需要考虑当前的系统文化。虽然 对返回字符串的格式没有确切要求, 它应该试图反映对象所感知的价值 用户。 ToString 的默认实现获取的名称 引发当前异常的类、消息、结果 在内部异常上调用 ToString,以及调用的结果 环境.StackTrace。如果这些成员中的任何一个为 null,则其值为 不包含在返回的字符串中。

【讨论】:

  • 我正在使用此方法记录ReflectionTypeLoadException,它不会从嵌套的LoaderException 条目中输出详细信息。我得写一个特例。
  • JetBrains 抱怨前任不需要 .ToSring()。不知道为什么
  • 某些方法(如Console.WriteLine())在传入对象时会隐式调用ToString。如果不需要,将其删除也无妨。
【解决方案2】:

我有这个非常适合我的目的的扩展方法。

public static class ExceptionExtensions {
    public static string ToMessageAndCompleteStacktrace(this Exception exception) {
        Exception e = exception;
        StringBuilder s = new StringBuilder();
        while (e != null) {
            s.AppendLine("Exception type: " + e.GetType().FullName);
            s.AppendLine("Message       : " + e.Message);
            s.AppendLine("Stacktrace:");
            s.AppendLine(e.StackTrace);
            s.AppendLine();
            e = e.InnerException;
        }
        return s.ToString();
    }
}

并像这样使用它:

using SomeNameSpaceWhereYouStoreExtensionMethods;
try {
    // Some code that throws an exception
}
catch(Exception ex) {
    Console.WriteLine(ex.ToMessageAndCompleteStacktrace());
}

更新

由于我收到了对此答案的支持,我想补充一点,我已停止使用此扩展方法,现在我只使用exception.ToString()。它提供了更多信息。所以,请停止使用这种方法,而使用.ToString()。 请参阅上面的答案。

【讨论】:

  • 因为您的更新而投票赞成!
  • 我对@H.Wolper 投了赞成票,因为他投票(批准)了旧投票用户的“更新”。
  • Exception.ToString 没用。我使用相同的基本非递归算法调整了 AggregateException.Flatten 的源代码以实际展平所有异常,而不仅仅是 AggregateExceptions。这将返回一个平面异常列表,其中包括每个异常,包括 AggrgateExceptions 本身和其中的单个异常及其子异常等。这使您能够按类型、消息等过滤掉异常,并最终构造一个包含有用信息的字符串。例如,您可以过滤掉“查看内部异常以了解详细信息”之类的消息。
  • @Maarten - ex.ToString() not 不包含异常可能具有的任何特殊属性吗?也许FooException 有一个int FooSize 和一个string FooCode。这些不会包含在ToString();
  • @Matthew 你可能是对的。但是我的答案中的扩展方法也也不包含该信息。
猜你喜欢
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多