如何在不丢失任何c#信息的情况下向异常添加消息?

本文关键字:情况下 异常 添加 消息 信息 任何 | 更新日期: 2023-09-27 17:54:15

我有以下代码:

catch(Exception ex)
{
    throw new FatalException("An error occurred while trying to load the XSLT file.", ex);
}
不幸的是,

只包含了Exception。我可以通过执行以下操作来修复此问题:

catch(Exception ex)
{
    throw;
}

但是我仍然想包含自定义消息来帮助记录事件。

如何在不丢失任何信息的情况下将此消息添加到异常中?(堆栈跟踪/调试符号等)

如何在不丢失任何c#信息的情况下向异常添加消息?

如果您只需要向原始异常添加信息,例如用户可读的消息或对您跟踪错误有用但对最终用户无用的特定详细信息,则可以使用异常的Data属性,这是一个键/值对字典。

我们广泛地使用它来记录信息,例如正在执行的报告或正在处理的文件,以便操作可以确定错误发生时究竟发生了什么。用户不需要这些细节,因为他们正在直接处理故障原因。

您还可以使用它来传递对用户有意义的纯文本消息。唯一的问题是,为了提取数据并使其对消费者有用,您将不得不在日志框架或最终用户界面中执行一些额外的工作。

例如,您可以这样做:

catch (Exception ex)
{
    ex.Data.Add("UserMessage", "An error occurred while trying to load the XSLT file.");
    throw;
}

然后在客户端代码中,您可以测试UserMessage是否存在,如果存在,则将其呈现给用户,而不是Exception:

catch (Exception ex)
{
    if (ex.Data.Contains("UserMessage"))
    {
        MessageBox.Show(ex.Data["UserMessage"].ToString());
    }
    else
    {
        MessageBox.Show(ex.Message);
    }
}

原来的Exception仍然存在。

当你做异常日志记录时,你收到的异常将是你用你的消息创建的FatalException。原来的Exception在ex.InnerException中。你可以继续循环InnerException,直到它为空,以获得所有的堆栈跟踪信息,等等。

总之,不要。

我相信你可以找到一些方法来解决这个问题,但我要强烈提醒你不要这样做。它违背了。net中异常的最初设计。异常不仅仅是为了帮助记录日志,它们还提供了有关应用程序失败的原始原因的信息。

通常首选使用第一个选项,因为它维护原始异常的堆栈跟踪,但允许您通过将其包装在单独的异常中来提供附加信息。在我自己的代码中,每当我记录异常时,我的日志记录函数将通过InnerException属性递归查找有关错误的每一点有用信息。

以防有人需要一个好的答案。关键是使用AppDomain.CurrentDomain.FirstChanceException

你可以用IDisposable创建一个自定义对象来放置所有的信息。如果发生异常,则FirstChanceException处理程序获取该信息并填充exception . data。

使用本地线程存储使其线程安全。然后,捕获它的代码将获取数据并记录它。

的例子:

using(MyCustomMessage.EnterToLocalStorage("Info for logging"") ) 
{ 
...code 
...exception thrown
.... FirstChanceException examines local thread storage and get's "info for logging" and puts into Exception.Data. 
} 
//Dispose is called and all messages that were put into LocalStorage are removed. 
//So if exception was not thrown before then it like nothing happened.

Google AsyncDiagnosticStack就是一个很好的例子。https://github.com/StephenCleary/AsyncDiagnostics/blob/master/src/Nito.AsyncEx.AsyncDiagnostics/AsyncDiagnosticStack.cs