在ASP.NET中使用企业库异常处理应用程序块 - 代码审查

时间:2009-11-17 19:07:01

标签: asp.net exception-handling enterprise-library

我正在构建的ASP.NET应用程序中实现企业库异常处理应用程序块。我计划通过将以下代码放在我的Global.asax.cs中来处理未捕获的应用程序异常:

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

我相信这将有助于处理策略的各种后处理操作(None,NotifyRethrow,ThrowNewException),但我想知道是否有人发现此实现存在重大问题。

3 个答案:

答案 0 :(得分:5)

我看到一些问题:

  • 您可能希望在错误处理程序中处理HttpUnhandledException。这就是您的页面提出的大多数例外情况。

  • 我没有看到调用Server.ClearError()的句柄和恢复(PostHandlingAction = None)策略的值。基本上你的页面抛出异常而你什么都不做。在最佳情况下,用户会看到一个空白页面。最糟糕的情况是,您可能会有一个部分呈现的页面,但没有指示发生了什么。

  • 我也没有看到可能从错误处理程序中抛出异常的意义。您要么最终得到黄色的死亡屏幕,要么强制要求调用另一个错误页面(例如web.config中定义的customErrors重定向)。

  • 你的HandleException逻辑没有考虑NotifyRethrow场景。 (基于注释有一个customError重定向删除)

使用@vladhorby's ErrorPage并保持主逻辑可以得到如下内容:

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由于某种原因抛出异常,你可能会在无限循环中结束,所以请确保ErrorPage.aspx有自己的Page_Error来尝试避免未处理的异常传播到全局错误处理程序。

  • 没有考虑异议2和3. :)

我不确定您的情况和要求,但您是否考虑过使用ELMAH

答案 1 :(得分:0)

看起来很好,但您可能想要重定向到错误页面而不是重新抛出(它的用户更友好):

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

答案 2 :(得分: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. 我正在使用来自this question的MVC“Server.Transfer”方法。
  3. 默认重定向是ErrorController上的一个操作,它从HttpContext中检索错误并对其进行适当处理。