2012-01-13 50 views
1

我正在處理一個泛型類,並且正在處理錯誤。我正在使用一個try catch在一個地方,我得到一個錯誤。問題是,如何將該錯誤返回給調用方法?如何正確處理泛型類中的錯誤?

public static DataTable GetData(string connString, string sqlStatement, Action<iDB2ParameterCollection> parameters) 
    { 
     DataTable dt = new DataTable(); 

     using (iDB2Connection conn = new iDB2Connection(connString)) 
     { 
      using (iDB2Command cmd = new iDB2Command(sqlStatement, conn)) 
      { 
       conn.Open(); 
       if (parameters != null) { parameters(cmd.Parameters); } 
       try 
       { 
        using (iDB2DataAdapter da = new iDB2DataAdapter(cmd)) { da.Fill(dt); } 
       } 
       catch (iDB2SQLErrorException e) 
       { 
       } 

       conn.Close(); 
      } 
     } 

     return dt; 
    } 

回答

1

我們做到這一點,出於同樣的原因,你似乎做它。這樣可以確保連接已關閉。

我們只是重新拋出相同的錯誤,並在「finally」塊中丟失連接。這樣可以關閉連接,並仍然將連接回復給調用者,因爲無論如何「finally」塊都會被執行。

catch (iDB2SQLErrorException e) 
{ 
    throw e; 
} 
finally 
{ 
    cn.Close(); 
} 

上面的代碼是什麼,我們已經使用了多年,但由於意見,我認爲這可能需要調整。有關如何通過異常處理來保存堆棧跟蹤的信息,請參閱此博客文章:http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx

+0

現在這是更多的線路,我想弄明白。 – 2012-01-13 22:25:28

+1

拋出e;'而不是拋出';清除原始調用堆棧中的異常? – 2012-01-13 22:26:37

+0

@GregB正確,所以在嘗試調試問題時這會有一個很大的缺點。這就是爲什麼我不是粉絲。 – 2012-01-13 22:29:08

5

通過不捕獲它在一個基類!

我不喜歡在基類級捕獲和吞嚥異常。

讓你的派生類擔心這些細節。

旁註(位置證據): 你會發現,在幾乎所有的API,該doucmentation將報告什麼異常情況將與班被拋出。如果他們想把他們趕進基礎班,他們已經有效地吞下了他們,使你無法成爲上課的使用者。

其他文章:

...而不是基於細節寫我們的抽象中,我們應該 寫一個基於抽象的細節。

這是依賴倒置原理的核心租戶。

看看這篇文章的一些真正好的東西在你的設計過程中考慮,http://www.oodesign.com/design-principles.html

+0

哦。所以讓調用代碼處理它? – 2012-01-13 22:14:03

+1

@MikeWillis絕對!這是正確的做法。你不僅使它幾乎不可能處理它們。你也爲自己設定了想要了解派生類將引發異常的每種可能情況。 (你不能這樣做,也不應該)。 – 2012-01-13 22:17:48

+0

我還沒有做過這麼普遍的事情(至少在我的世界裏),所以我不確定我是否應該處理這些錯誤。 – 2012-01-13 22:21:41

0
  1. 您可以實現一些邏輯來處理,以內部例外在這個方法並重新拋出它。異常會在調用堆棧中冒出來;
  2. 其他選項是使用錯誤代碼在堆棧中傳遞錯誤。這取決於API。
0

要麼不抓住它,讓來電處理它,或者拋出自己的錯誤,它包裝的原之一:

class DataRetrievalException : Exception { 
    DataRetrievalException(String message, Exception cause) : base(message, cause) {} 
} 

// ... 
catch (iDB2SQLErrorException e) { 
    throw new DataRetrievalException("Error retrieving data from database", e); 
}