2011-06-02 70 views
2

我想知道是否有合理的方法來定製.NET框架引發的異常的消息?以下是我經常編寫的一段代碼,可以在許多不同的場景中實現爲用戶提供合理的異常消息的效果。自定義.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(); 
} 

無論如何,我不認爲這樣的功能存在,但如果它沒有我會確實非常高興。有沒有人處理過這種類型的問題?它看起來像我要結束需要一些類型的擴展方法到最後...

回答

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(); 
3

除非我錯過了你的問題中的東西,這正是你應該做的。我很確定每個例外都包含一個以string message作爲參數的過載。如果您想提供超出.NET提供的「默認」的信息,則需要設置特定的消息。

+0

我想每個人都錯過了這個問題。我知道當我嘗試訪問字典時會出現'KeyNotFound'。我只是想改變這個EXCEPTION包含的信息。我不覺得它是非常有用的做檢查自己,或抓住原來的例外。 – 2011-06-02 17:10:10

0

異常是一個對象。與大多數對象一樣,無法控制創建者如何創建對象,無論創建者是否爲.NET Framework。

你甚至可以告訴.NET Framework在哪些情況下創建什麼消息?在發佈的情況下,您需要在KeyNotFoundException上發送一條消息,而在其他情況下則需要發送另一條消息。你如何區分這兩種情況?

2

只從KeyNotFoundException類繼承並重寫Message屬性以生成更有意義的消息,然後使用具有適當構造函數的自己的異常類。這正是繼承意味着什麼,增加了價值。即

throw new MetaDataKeyNotFoundException(string metaDataKey); 
+0

但看看他的問題。繼承無法幫助他實現他的目標。他已經通過用自己的消息文本拋出自己的例外來「壓倒」消息。 – 2011-06-02 15:23:38

+0

爲什麼要在他拋出異常的構造函數中提供正確的消息時遇到那麼多麻煩?任何可以拋出異常的*代碼都應該封裝在'try/catch'中(* - 給定值爲「any」)。 – AllenG 2011-06-02 15:24:09

+0

好吧,它可能像'拋出新的MetaDataKeyNotFoundException(字符串metaDataKey);'這將更加簡潔。 – 2011-06-02 15:26:52

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)); 
    } 
} 
+3

這樣你就失去了堆棧軌跡的一部分。我會將原始異常添加爲拋出的異常。 – codeConcussion 2011-06-02 16:11:28

+0

@whatknott絕對。我寫的簡潔,但你是正確的。 – 2011-06-02 19:04:35

+0

爲什麼這是我原來的方法更好的選擇?或者僅僅是不同的語法? – 2011-06-09 19:48:01

1

Exception類已經支持添加對應特定的事件或場景,其中通過使用屬性Exception.Data的錯誤發生的自定義用戶數據。

從MSDN進入該屬性,強調的是我的:

獲取提供有關異常用戶定義的其他信息鍵/值對的集合。

我知道你正在尋找覆蓋Message財產,但使用Data可以實現通過只是確保異常處理程序知道如何處理這些額外的數據相同。

+0

是的,但我試圖避免額外的try/catch塊。對於其他場景,這是一個相當不錯的方法,雖然... – 2011-06-02 17:37:56

0

KeyNotFoundException.SetMessage(「這個 是我的自定義消息!「);

沒有這樣的功能(除了搞亂內部或資源也許)但是它應該如何工作你會改變消息的每一段使用異常的代碼 - 對一些其中你的新消息根本沒有意義

考慮一些任意使用Dictionary類,甚至是一些完全不同的代碼,它遵循重用現有異常類型的「最佳實踐」,它們都會突然使用你的(非常)自定義錯誤信息。

+0

是的,就像我說過的,我不認爲這樣的特性存在。當然,如果有的話,我希望沒有人會愚蠢地實施它來提供你所描述的行爲。 – 2011-06-03 11:56:18