自定义.NET框架生成的异常消息?

时间:2011-06-02 15:17:57

标签: c# .net exception exception-handling customization

我想知道是否有合理的方法来自定义.NET框架抛出的异常消息?下面是我在许多不同场景中经常编写的一大块代码,以实现向用户提供合理的异常消息的效果。

public string GetMetadata(string metaDataKey)
{
  // As you can see, I am doing what the dictionary itself will normally do, but my exception message has some context, and is therefore more descriptive of the actual problem.
  if (!_Metadata.ContainsKey(metaDataKey))
  {
    throw new KeyNotFoundException(string.Format("There is no metadata that contains the key '{0}'!", metaDataKey));
  }

  // This will throw a 'KeyNotFoundException' in normal cases, which I want, but the message "The key is not present in the dictionary" is not very informative.  This is the exception who's message I wish to alter.
  string val = _Metadata[metaDataKey].TrimEnd();
  return val;
}

正如您所看到的,我实际上只是为了使用不同的(更好的)消息而生成重复的代码。

修改
我在寻找什么,基本上是这样的:

KeyNotFoundException.SetMessage("this is my custom message!")
{
// OK, now this will send off the message I want when the exception appears!
// Now I can avoid all of that silly boilerplate!
string val = _Metadata[metaDataKey].TrimEnd();
}

无论如何,我不认为这样的功能存在,但如果确实存在,我会非常高兴。有没有人以前解决过这类问题?看起来我最终还是需要某种类型的扩展方法......

7 个答案:

答案 0 :(得分:3)

除非我在你的问题中遗漏了什么,否则这正是你应该做的。我很确定每个异常都包含一个以string message为参数的重载。如果要提供.NET提供的“默认”之外的信息,则需要设置特定的消息。

答案 1 :(得分:3)

您似乎以正确的方式开始这样做。但是,我会更改您检查异常的方式:

public string GetMetadata(string metaDataKey)
{
    try
    {
        string val = _Metadata[metaDataKey].TrimEnd();
        return val;
    }
    catch (KeyNotFoundException ex)
    {
        // or your own custom MetaDataNotFoundException or some such, ie:
        // throw new MetaDataNotFoundException(metaDatakey);
        throw new KeyNotFoundException(string.Format("There is no metadata that contains the key '{0}'!", metaDataKey));
    }
}

答案 2 :(得分:2)

只需从KeyNotFoundException类继承并覆盖Message属性以生成更有意义的消息,然后使用您自己的异常类和适当的构造函数。这正是继承的意义所在,增加了价值。即。

throw new MetaDataKeyNotFoundException(string metaDataKey);

答案 3 :(得分:1)

Exception类已经支持通过使用属性Exception.Data添加与发生错误的特定事件或方案关联的自定义用户数据。

从该属性的MSDN条目,重点是我的:

  

获取一组键/值对,这些键/值对提供有关异常的其他用户定义信息

我知道您要覆盖Message属性,但使用Data只需确保异常处理程序知道如何处理这些额外数据即可实现相同目的。

答案 4 :(得分:0)

异常是一个对象。与大多数对象一样,无论创建者是否为.NET Framework,您都无法控制创建者创建对象的方式。

您如何告诉.NET Framework在哪种情况下创建哪些消息?在您发布的情况下,您希望KeyNotFoundException上有一条消息,而在不同的情况下则需要另一条消息。你如何区分这两种情况?

答案 5 :(得分:0)

  

KeyNotFoundException.SetMessage(“这   是我的自定义消息!“);

没有这样的功能(除了搞乱内部或资源)。但无论如何它应该如何运作。您将为使用该异常的每一段代码更改消息 - 其中一些代码根本没有任何意义。

考虑一些Dictionary类的任意使用,甚至是一些完全不同的代码,这些代码遵循重用现有异常类型的“最佳实践”,所有这些代码都会突然使用您的(非常多)自定义错误消息

答案 6 :(得分:0)

这是我提出的一个解决方案,但我想指出它更像是一个补丁而不是任何东西。它确实有效,但可能并不适合所有应用程序。我甚至都想不出一个好名字。

  public class ContextDictionary<TKey, TValue> : Dictionary<TKey, TValue>
  {
    public TValue this[TKey key, string context]
    {
      get
      {
        if (!this.ContainsKey(key))
        {
          throw new KeyNotFoundException(string.Format("There is no {0} that contains the key '{1}'!", context, key));
        }
        return this[key];
      }
      set { this[key] = value; }
    }
  }

所以现在我可以这样说,并获得我真正想要的更具描述性的异常消息。

var _MetaData = new ContextDictionary<string,string>();
string val = _Metadata[metaDataKey, "metadata"].TrimEnd();