向自定义异常添加额外信息

13

我已经为可能出现的一个非常具体的问题创建了一个自定义异常。当我从另一个系统接收数据并尝试解析时,如果解析失败,我就会引发这个异常。在我的自定义异常中,我添加了一个名为“ResponseData”的字段,以便跟踪确切地出了什么问题。

在这种自定义异常中,额外的响应数据应该放在异常的“message”属性中吗?如果放在那里,消息可能会很大。我有点想在那里放置它,因为我正在使用Elmah,这是我获取该数据的方式。

因此,问题要么是: - 如何让Elmah记录自定义异常中字段的额外信息 或者 - 额外的异常详细信息是否应该放入“message”属性中?

6个回答

13
在像这样的自定义异常中,那个额外的响应数据应该放在异常的“消息”中吗?
不,正如Sören已经指出的那样。但是,您的异常类型可以覆盖ToString并在其中合理地添加响应数据信息。这是许多BCL(基类库)异常类型遵循的非常普遍的做法,因此您不会发现自己在逆流而行。例如,请查看SSCLI (Rotor)System.IO.FileNotFoundException.ToString实现。
public override String ToString()
{
    String s = GetType().FullName + ": " + Message;

    if (_fileName != null && _fileName.Length != 0)
        s += Environment.NewLine + String.Format(Environment.GetResourceString("IO.FileName_Name"), _fileName);

    if (InnerException != null)
        s = s + " ---> " + InnerException.ToString();

    if (StackTrace != null)
        s += Environment.NewLine + StackTrace;

    try
    {
        if(FusionLog!=null)
        {
            if (s==null)
                s=" ";
            s+=Environment.NewLine;
            s+=Environment.NewLine;
            s+="Fusion log follows: ";
            s+=Environment.NewLine;
            s+=FusionLog;
        }
    }
    catch(SecurityException)
    {

    }
    return s;
}

正如您所看到的,它附加了FusionLog属性的内容,该属性代表在程序集加载失败的情况下的额外信息。

我该如何让Elmah记录自定义异常中字段的额外信息?

ELMAH将调用异常的ToString方法的结果存储为错误的详细信息,因此如果您按照规定实现了ToString方法,则信息将被记录而无需进一步处理。唯一的问题是记录的详细信息将是非结构化文本。


7
你不应该在.Message中填写调试信息,而应该填写简洁、有用的文本。

http://msdn.microsoft.com/en-us/library/system.exception.message.aspx

“Message”属性的文本应该完整描述错误,并在可能的情况下解释如何纠正错误。当调用ToString方法时,“Message”属性的值将被包含在返回信息中。
只有在创建异常时才会设置“Message”属性。如果没有向当前实例的构造函数提供消息,则系统会提供一个默认消息,该消息使用当前系统区域设置进行格式化。
继承者注意事项:在需要控制消息内容或格式的类中重写“Message”属性。当应用程序代码需要显示已捕获异常的信息时,通常访问此属性。
错误消息应该本地化。
响应数据不符合描述要求。
我不熟悉elmah,无法告诉您如何在使用它的同时扩展“Exception”类。elmah是否实现了自己的“Exception”子类?还是一个接口?您可以自己创建子类吗?

5

异常类包含一个字典(我相信它被命名为Data),您可以使用它来将自定义数据与基本异常相关联。


请记住,如果一个异常被序列化,那么它内部的所有内容也都需要是可序列化的 - 因此,如果您的对象很复杂,最好只提取出您需要的部分。 - Simon_Weaver

1

我不完全理解你的问题,但你似乎在问如何处理额外的异常数据,如果这不是你的问题,请随意忽略。

我认为一个重要的问题是异常消息到底是用来干什么的?它不是用来知道异常来自哪里的,堆栈跟踪是用来做这个的;它也不是用来将异常封装在更一般的异常中,应该使用InnerException字段来完成;在你的异常只从代码的特定位置引发的情况下,它甚至不是用来描述你遇到了什么样的错误 - 这就是异常类型的作用。

通常我使用消息字段提供简单、易于理解的提示,让第一次看到这个错误的程序员可以理解底层系统。我认为消息字段适合提供一个简短(一句话)的解释,一个提示,说明这个错误经常如何引发,或者一个参考资料。

所以,就我理解的而言,我认为存储从另一个系统接收到的“附加信息”的最佳方法是作为InnerException。我不知道Elmah,但如果它值得一试,它会检查InnerExceptions并存储它们。


0
我不明白这个问题——你正在扩展 System.Exception,而且你已经添加了 Elmah 字段。那就是它应该存在的地方——作为异常本身的公共属性。

0

Elmah是一个记录未处理异常的http模块。

我猜这只是Elmah的限制,因为它不存储自定义字段。我想我得问那些人。我在响应数据中有额外的字段,但是Elmah不会存储它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接