簡體   English   中英

try-catch每個數據庫連接?

[英]try-catch every db connection?

是否建議在每個打開數據庫連接的函數中放置一個try-catch塊並在那里記錄錯誤,或者我是否應該在應用程序的更高層中捕獲錯誤?

public static Category GetCategoryByName(string name)
{
    Category result;
    try
    {
        using (IDbConnection conn = ConnectionHelper.CreateDbConnectionByName(_connectionStringName))
        {
            conn.Open();
            using (IDbCommand cmd = conn.CreateCommand())
            {
                //do stuff
            }
        }
    }
    catch(Exception e)
    {
         // log error here?
    }
    return result;
}

更確切地說

try
{
    Category myCat = DataTools.GetCategoryByName("myCat");
    // other stuff
}
catch(Exception e)
{
   // log error here?
}

總結一下:代碼中應該盡早發現錯誤嗎? 或者我應該在有關上下文的更多信息的地方抓住它們?

一如既往,它取決於,但一般情況下,如果你可以做一些事情,或者你有特定的代碼(例如重試)發生只捕獲異常,否則,讓異常冒泡,最頂層可以記錄它/以集中的方式處理它。

任何其他方式都會導致大量日志記錄代碼散布在所有業務邏輯中。

捕獲異常時,請始終嘗試使用最准確的異常。 例如,在使用SQL Server時,請捕獲SqlException,因為它將包含有關exceptin的更多信息,而不是一般的Exception。 您可以獲得實際的行號和其他有用的診斷信息。

在提取並記錄了所有相關的內容之后,重新拋出異常或將其包裝在不太具體的異常中,例如InvalidDataException或Exception並拋出它。 然后,您可以在更高級別捕獲這些更通用的異常。

try
{
    // Execute DB call here
}
catch(SqlException exp)
{
    // Log what you need from here.
    throw new InvalidOperationException("Data could not be read", exp);
}

從更高級別調用此方法時,您可以捕獲InvalidOperationException。 如果更高級別確實需要更多細節,則InnerException將提供可以訪問的SqlException。

我遵循的異常處理的一般方法是僅捕獲我可以有用地執行的操作。 在較低級別的代碼中捕獲真正的一般異常是沒有意義的,因為您可以真正期望一切都出錯或者能夠從每個異常中恢復,例如OutOfMemoryException或StackOverflowException。

我更喜歡第一種方法,但是你還需要弄清楚我還能做些什么來阻止...

  • 重新拋出異常?
  • 扔另一個(更普遍的)例外?
  • 將null返回給調用者?

我通常只處理UI中的異常,下面的所有內容我總是把它扔回頂層。 這樣,堆棧跟蹤一直保持不變。 你總是可以記錄並扔掉它。

我之前也用過這個:


try
{
   DB Command
}
catch (Exception ex)
{
   Log(ex)
   throw; //preserve stacktrace
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM