ExceptionContext.ExceptionHandled变为true。异常处理在哪里进行?

6 浏览
0 Comments

ExceptionContext.ExceptionHandled变为true。异常处理在哪里进行?

我正在使用一个全局操作过滤器来处理和记录所有的异常。

这是全局操作过滤器ElmahHandleErrorAttribute的定义 - 它重写了OnException方法。

我不明白为什么当OnException方法执行时,context.ExceptionHandled的值为true。

这个异常是如何被处理的?

-编辑-

我在Web.Config中有一个customErrors部分。我有一个ErrorController类,还有一个叫做General和Http404的操作。

我不明白的是,控制器操作General没有被执行(断点从未被命中),但是当ElmahHandleErrorAttribute的OnException方法开始执行时,ExceptionContext.ExceptionHandled的值被设置为true。

0
0 Comments

当发生异常时,全局过滤器的执行顺序是反向的。这意味着HandleErrorAttribute首先运行。

HandleErrorAttribute的代码可以在这里查看,但简而言之,它的功能包括:

  1. 只有当ExceptionHandled为false并且启用了自定义错误时,才执行。
  2. 设置一个重定向到错误视图,默认情况下称为Error
  3. ExceptionHandled设置为true。

由于它是第一个过滤器,所以当它执行时,ExceptionHandled为false,导致它将视图设置为Error并将ExceptionHandled设置为true。所以,当您自己的过滤器执行时,ExceptionHandled已经设置为true。请注意,如果禁用了自定义错误,则ExceptionHandled仍将为false,因为HandleErrorAttribute不会执行其操作。在这种情况下,ELMAH仍会记录错误,因为它是未处理的(黄屏幕错误),因此您的类中的测试是为了防止错误重复记录。

现在,关于为什么General操作未执行的问题,只有在过滤器没有设置某些明确的重定向时,defaultRedirect才会被使用,所以当在ActionMethod内部发生异常并且注册了全局过滤器HandleErrorAttribute时,它实际上会被忽略。但是,如果您输入不存在的URL,即在ActionMethod之外发生的错误,则会调用它。此外,如果您在Global.asax.cs中注释掉注册HandleErrorAttribute的行,则始终会执行General控制器操作。

谢谢您的解释。它确实帮助了我。我希望ElmahHandleErrorAttribute成为首个执行的过滤器。设置这个自定义过滤器的顺序能解决这个问题吗?根据这个评论(stackoverflow.com/a/9163926/1242061),我应该给我想要首先执行的过滤器一个更高的Order值。

是的,我认为您可以尝试调整Order属性(但不确定如何在全局过滤器上这样做,只在使用属性时这样做过)。只需反转在RegisterGlobalFilters中添加过滤器的顺序即可...当发生错误时,最后添加的过滤器将首先运行。不确定为什么您希望ELMAH首先运行,如果您确实希望这样做,那么您不能检查ExceptionHandled,因为在这种情况下它始终为false。

我在注册过滤器时指定了顺序。现在我的自定义过滤器ElmahHandleErrorAttribute首先处理错误。关于您的问题不确定为什么您希望ELMAH首先运行,您认为这是个坏主意吗?我这样做是因为我想显示自定义错误页面并检查错误类型并显示特定视图。

只要ELMAH视图始终显示一个视图,那么是的,我认为这是可以的。但是,如果您让默认的HandleErrorAttribute处理回退情况,如果也没有设置视图,那么将会发生YSOD,并且您可能最终会在ELMAH中记录错误两次(一次在全局过滤器中,一次在异常未标记为已处理时)。如果您在ELMAH过滤器中设置视图,那么也许您应该完全摆脱HandleErrorAttribute

我猜我应该摆脱HandleErrorAttribute。自定义的ElmahHandleErrorAttribute将显示一个视图。由于我在global.asax中定义了Application_Error()来处理404和其他未处理的异常,所以我认为不会显示YSOD。

0