2009-11-17 36 views
2

我正在構建的ASP.NET應用程序中實現企業庫異常處理應用程序塊。我打算通過將下面的代碼在我的Global.asax.cs來處理未捕獲的應用程序異常:在ASP.NET中使用企業庫異常處理應用程序塊 - 代碼審查

protected void Application_Error() 
    { 
     Exception error = Server.GetLastError(); 
     Exception errorToThrow; 

     if (ExceptionPolicy.HandleException(error, "Application Error", out errorToThrow)) 
     { 
      if (errorToThrow != null) 
       throw errorToThrow; 
     } 
     else 
      Server.ClearError(); 
    } 

我相信這將努力處理政策的各種後處理操作(無,NotifyRethrow,ThrowNewException )但我想知道是否有人看到這個實現的重大問題。

回答

5

我看到了幾個問題:

  • 你可能會想在你的錯誤處理器中處理HttpUnhandledException。這就是你的頁面提出的大多數例外情況。

  • 我看不到調用Server.ClearError()的句柄和恢復(PostHandlingAction = None)策略的值。基本上你的頁面已經拋出異常,你什麼都不做。最好的情況下,用戶看到一個空白頁面。最糟糕的情況是,你可能有一個部分呈現的頁面,但沒有說明發生了什麼。

  • 我也沒有看到可能從您的錯誤處理程序中拋出異常的問題。你要麼以死亡的黃色屏幕結束,要麼迫使另一個錯誤頁面被調用(例如,在web.config中定義的customErrors重定向)。

  • 您的HandleException邏輯不考慮NotifyRethrow方案。(根據評論有刪除,有一個customError重定向)

使用@vladhorby's ErrorPage,並保持你的主要邏輯會給這樣的事情:

  • 如果ErrorPage.aspx拋出:

    protected void Application_Error() 
    { 
        Exception error = Server.GetLastError(); 
    
        if (error is HttpUnhandledException) 
        { 
         error = error.InnerException; 
        } 
    
        Exception errorToThrow; 
    
        if (ExceptionPolicy.HandleException(error, "Application Error", out errorToThrow)) 
        { 
         Response.Redirect(string.Format("ErrorPage.aspx?Message={0}", Uri.EscapeDataString((errorToThrow ?? error).Message))); 
        } 
        else 
        { 
         Server.ClearError(); 
        } 
    } 
    


    關於上述代碼的幾點說明由於某些原因,您可能會在無限循環中出現異常,所以請確保ErrorPage.aspx具有自己的Page_Error,以避免未處理的exceptio ns傳播到全局錯誤處理程序。

  • 它沒有考慮到反對2和3 :)

我不知道你的處境和要求,但您使用ELMAH考慮?

+0

我的回答,用「鐵磨鐵」的方式: 1)我喜歡關於HttpUnhandledException的觀點。我會包括那張支票。 2)由於你提到的原因,我也沒有看到PostHandlingAction = None策略的價值,但我會將這個問題推遲到政策而不是這裏。 3)根據我對vladhorby的回答,我未能指定我將customErrors配置爲根據所產生的錯誤的HTTP狀態代碼進行重定向,無論是原始錯誤還是重新拋出的錯誤。 4)我認爲重新拋出異常並沒有考慮到notifyRethrow場景。我錯過了什麼嗎? – 2009-11-18 17:42:57

+0

第3點是主觀的 - 我寧願把所有東西放在一起。對於第4點......好吧,我看到......你正在使用一個customError標籤來處理來自你的處理程序的未處理的異常,並讓NotifyRethrow沒有處理程序只是冒泡到那個處理程序。 :) – 2009-11-18 20:08:39

+0

爲您的第一個最後的筆記+1,我意外地將該錯誤引入到一個網站之前,無法弄清楚爲什麼Firefox一直告訴我,我的網頁將無限重定向。 – 2010-02-23 15:56:36

0

看起來不錯,但你可能要重定向到一個錯誤頁面,而不是重新拋出(它是用戶友好的):

Exception wrappedEx; 
ExceptionHandlerHelper.ExceptionHandler.HandleException(ex, "MyPolicy", out wrappedEx); 
Response.Redirect(string.Format("ErrorPage.aspx?Message={0}", Uri.EscapeDataString((wrappedEx ?? ex).Message))); 
+0

我意識到我沒有在我的問題中指定這個,但我在web.config中設置了自定義錯誤處理,以便在EHAB有機會查看異常之後將用戶重定向到友好的錯誤頁面。 – 2009-11-18 17:36:19

0

對於那些有興趣的人,我基於我遇到的一些問題更新了我的代碼。具體來說,我希望用戶看到一個錯誤頁面,但沒有更改URL,所以我不能依賴web.config自定義錯誤處理。我發現這個方法讓我對錯誤處理有了更多的控制。

if (this.Context.IsCustomErrorEnabled) 
{ 
    Exception originalError = Server.GetLastError(); 
    Exception replacedError; 

    if (ExceptionPolicy.HandleException(originalError, "Application Error", out replacedError)) 
    { 
     if (replacedError != null) 
      this.Context.Items[ErrorController.ExceptionKey] = replacedError; 
     else 
      this.Context.Items[ErrorController.ExceptionKey] = originalError; 

     Server.ClearError(); 

     // Perform an MVC "Server.Transfer" to the error page. 
     this.Context.RewritePath(DefaultRedirectUrl); 

     IHttpHandler handler = new MvcHttpHandler(); 
     handler.ProcessRequest(this.Context); 
    } 
} 

這個實現的一些注意事項:

  1. 「DefaultRedirectUrl」是拉從web.config文件中,這似乎是爲存儲信息的最合乎邏輯的地方默認錯誤重定向URL屬性。
  2. 我正在SO上使用this question的MVC「Server.Transfer」方法。
  3. 默認的重定向是對ErrorController的一個操作,它從HttpContext中檢索錯誤並對其進行適當的處​​理。
相關問題