【问题标题】:Is there an easy way to identify where an exception was thrown from the Exception object?是否有一种简单的方法可以确定从 Exception 对象引发异常的位置?
【发布时间】:2014-12-31 18:17:36
【问题描述】:

所以,如果我没记错的话,我似乎记得看到在 4.5 中向 C# 添加了一些新注释,这些注释允许您通过记录器或其他东西精确定位异常抛出的位置(类、方法、行)。但在此之前,是否有任何内置方法可以至少识别从实际异常对象引发异常的类和方法,而无需解析堆栈跟踪?我希望能够使用异常对象说,向日志输出一条消息,上面写着“Exception was thrown at MyProject.MyClass.MyMethod(int, string). Message: <exception message>

我知道有一些 3rd 方库可以帮助解决这个问题,但如果可能的话,我宁愿让它更简单,同时更多地了解 FCL。目的不是改变异常是什么,而是使它们在未处理的情况下更有用。例如,一个未处理的异常被抛出并被过滤器捕获。过滤器记录异常并重新抛出它。如果创建的日志可以声明“它被扔在这里,请参阅完整的堆栈跟踪以获取更多信息”,那就太好了。这将使我们更快地查看 where 而不必浏览堆栈跟踪,在某些情况下(至少对于我们的一些旧东西)可能会非常误导,导致追逐我们的尾巴只是发现如果我们准确地从哪里开始,我们会很快找到问题。

【问题讨论】:

  • 您必须确保您的 pdb 包含在您的构建中,否则您可能正在考虑创建自己的异常对象,该对象将为您执行堆栈跟踪/源解析并吐出一条你喜欢的消息。
  • @JohnSaunders,堆栈跟踪中有很多噪音。它显然对更深层次的故障排除很有用,但对于某些人来说,它需要经历很多。我正在尝试输出更具可读性的内容。尤其是在我们这里有所有这些遗留异常处理时,堆栈跟踪在消息传递时会丢失。这很愚蠢,但如果我至少可以在消息中添加一些有用的东西,即使跟踪丢失,我们仍然能够看到错误发生的哪里

标签: c# exception logging


【解决方案1】:

如果您确实需要从 Exception 对象中解析出各个帧,请使用 System.Diagnostics.StackTrace

using System;
using System.Diagnostics;

public class Program
{
    public static void Main(string[] args)
    {
        try
        {
            Thrower();
        }
        catch (Exception e)
        {
            var trace = new StackTrace(e);
            Console.WriteLine(trace.GetFrame(0).GetMethod());
        }              
    }

    private static string Thrower()
    {
        throw new Exception("Boom");
    }
}

您所指的功能称为Caller Info Attributes,本身与异常没有任何关系。它是主要用于故障排除的一般功能。该信息在您使用时在编译时插入到程序集中,类似于 C++ 中的__LINE____FILE____FUNCTION__ 宏。

【讨论】:

    【解决方案2】:

    对于异常的来源,您可以查看Exception.Source 属性,该属性提供如下信息:

    导致错误的应用程序或对象的名称。

    您不需要解析堆栈跟踪,它只是一个包含所有数据的字符串,在某些情况下可能会变得有用。请记住,exception 出现在特殊情况下,您需要尽可能多的信息。

    【讨论】:

    • Source 默认情况下只会给你程序集名称而不是方法名称/行号。
    • @mikez:正确,这就是为什么我添加了以任何方式使用堆栈跟踪字符串的解释
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多