我正在构建的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),但我想知道是否有人发现此实现存在重大问题。
答案 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);
}
}
关于此实施的一些注意事项: