2013-01-15 26 views
10

我按照這種方式處理我的應用程序中的異常。但是我的領導說我做錯了。我只是打包並重新拋出同樣的異常,這會影響性能。打包並重新拋出異常會影響性能嗎?

我的方法有什麼問題?有沒有人對我如何在這裏登錄和處理異常有任何建議?

public class BusinessRepository : IBusinessRepo 
{ 
    public List<Employee> GetEmployees() 
    { 
     try 
     { 
      //do some DB operations 
     } 
     catch (SQLException sqlex) 
     { 
      Logger.Log("Exception detail with full stack trace"); 
      throw new DALException(sqlex, "Error in data access layer"); 
     } 

    } 
} 
public class BusinessLayerClass : IBusinessLayer 
{ 
    private readonly IBusinessRepo Repo; 
    public BusinessLayerClass(IBusinessRepo rep) 
    { 
     Repo = rep; 
    } 
    public List<Employee> GetEmployees() 
    { 
     try 
     { 
      List<Employee> emps= return Repo.GetEmployees(); 
     } 
     catch (DALException dex) 
     { 
      //do nothin as it got already logged 
      throw; 
     } 
     catch (Exception ex) 
     { 
      Logger.Log(ex, "Business layer ex"); 
      throw new BusinessLayerEx(ex); 
     } 
    } 
} 

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     try 
     { 
      List <Employee>= BusinessLayerClass.GetEmployees(); 

     } 
     catch (DALException) 
     { 
      //show error msg to user 
     } 
     catch (BusinessLayerEx) 
     { 
      //show error msg to user 
     } 
     catch (Exception ex) 
     { 
      Logger.Log(); 
      //show error msg to user 
     } 
     return View(emps); 
    } 
} 

我是否遵循如上圖所示興高采烈和處理和日誌記錄的正確方法嗎?

+2

根據約翰斯波特的表現幾乎不會受到異常投擲的影響。請參閱:http://www.developerfusion.com/article/5250/exceptions-and-performance-in-net/ – albertjan

+2

由於異常應該是例外,它有多重要? – emartel

+0

@albertjan我同意Jon Skeet。但是,我的方法是處理和登錄的正確方法嗎? – Billa

回答

3

我傾向於同意你這樣做的方式同意,只要滿足兩個條件:

  1. Logger.Log日誌報表比你在這裏表示什麼更有意義的事情/有用(我猜你在這裏的代碼只是一個示例消息,指出錯誤被記錄)。如果它提供了可用於追查異常原因的信息,那就很好。
  2. //show error msg to user意見意味着,在該位置,您呈現一個很好的觀點,並解釋說有錯誤,你不只是顯示默認的異常屏幕/ STRACK痕跡。

至於你的throw;當你捕捉到DALException時,你只是拋出:沒關係。這裏的目標似乎是捕獲上一層出現的異常並記錄下來,然後拋出自己的異常。由於只有在您已經記錄了另一個錯誤並自行拋出它時纔會拋出DALException,因此讓它在這個級別上冒出來是完全正確的。

1

拇指例外的一般規則是不抓他們,除非你可以「做一些事情」,即增加價值。理想情況下,這將是一種優雅的恢復,以至於用戶從不知道有呃逆,但最起碼​​這包括記錄異常 - 你正在做什麼。

不僅立即捕捉異常,再次拋出它。這沒有增加任何價值。 (這可能是一個例外,如果您需要將異常類型更改爲更具信息性/適用於上下文的內容)。相比於任何正常返回機制

+0

他正在捕捉一個異常(做出變異或記錄信息)並*然後*重新拋出它,他沒有捕獲它什麼都不做,而是重新拋出相同的異常,所以這不適用。 – Servy

+0

catch-then-rethrow代碼就是在那裏從它後面的「catch,log,throw new exception」塊中過濾掉一個特定類型的異常(因爲如果問題已經存在,那種類型的異常只會被拋出已記錄)。 – yoozer8

+0

@Servy不,他正在抓住它,除了再次扔掉之外別無所求。他甚至在評論中說明他故意不做任何事情,爲什麼 - 「已經記錄下來」。 –

1

拋出和捕獲異常是昂貴的,但它是一種除了一點 - 我們不應該使用異常正常控制流機制,但處理異常的事情。

異常處理在技術上可能非常具有挑戰性。畢竟,大多數時候我們並不期望他們。但是,如果團隊或項目沒有任何種類的策略來進行錯誤處理,那麼什麼使得幾乎不可能得到異常處理「正確」。在理想的世界中,我們從一開始就知道我們需要應對哪種錯誤條件,並且我們會根據這些設計來設計整個應用程序(以及我們還需要記住的巨大的其他約束條件,從代碼可讀性到性能)。

我說,如果你的領導說:「這是錯誤的」,那麼它是公平地問:「什麼是我們的錯誤處理策略是什麼?」。如果你甚至不知道你的代碼應該達到什麼目的,你怎麼可能提供優秀的代碼?

0

沒有什麼不對您的做法,但我沒有看到你的自定義異常增加多少價值。如何在自定義異常中封裝特定的SQL異常(例如唯一鍵違例),以便您的UI可以呈現有意義的錯誤消息,DAL中如何封裝異常可以增加值的示例是。

至於表現,無論如何都不重要,因爲已經發生了非常糟糕的事情。

+0

我總是聽到同樣的聲音,但它的影響非常糟糕,但是由於你說了什麼,或許它的影響只是在調試的時候......除了在投擲之前進行大量檢查以及超時之外,這可能會讓人相信。仍然,認爲第一批人是對的,我有一個異常來臨,我想將它們改爲特定類型的異常,然後混淆整個應用程序異常,是否可以捕獲,重新創建新實例並重新拋出它?有沒有提高性能的方法? – deadManN

+1

您可以閱讀Jon Skeet的第一條評論中的鏈接,以更好地理解異常和性能(http://www.developerfusion.com/article/5250/exceptions-and-performance-in-net/)。我的觀點是,對於大多數應用程序,您應該以對應用程序有意義的方式處理異常,而不必擔心性能。 –