2

I want to override the HandleErrorAttribute with a new version called something like HandleErrorsWithLogging. Essentially, I want it to log the unhandled exception to my log file and then proceed with the typical 'Redirect to ~/Shared/Error' functionality you get with HandleError.

I am already adding HandleError to all my actions in the global.asax

Is this the best approach or is there some easier way to gain access to that unhandled exception for logging purposes? I had also though about an Ajax call on the Error view itself.

Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73

2 Answers2

6

You can create a custom filter that inherits from FilterAttribute and implements IExceptionFilter. Then register it in global.asax.cs. Also you must enable custom errors handling in the web.config:

<customErrors mode="On"/>  


    public class HandleErrorAndLogExceptionAttribute : FilterAttribute, IExceptionFilter
        {
            /// <summary>
            /// The method called when an exception happens
            /// </summary>
            /// <param name="filterContext">The exception context</param>
            public void OnException(ExceptionContext filterContext)
            {
                if (filterContext != null && filterContext.HttpContext != null)
                {
                    if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
                    {
                        // Log and email the exception. This is using Log4net as logging tool
                        Logger.LogError("There was an error", filterContext.Exception);

                        string controllerName = (string)filterContext.RouteData.Values["controller"];
                        string actionName = (string)filterContext.RouteData.Values["action"];
                        HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

                        // Set the error view to be shown
                        ViewResult result = new ViewResult
                        {
                            ViewName = "Error",
                            ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                            TempData = filterContext.Controller.TempData
                        };

                        result.ViewData["Description"] = filterContext.Controller.ViewBag.Description;
                        filterContext.Result = result;
                        filterContext.ExceptionHandled = true;
                        filterContext.HttpContext.Response.Clear();
                        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                    }
                }
            }
Flavia
  • 563
  • 4
  • 9
1

Overriding the HandleError attribute is indeed one approach into handling this. There are other approaches as well. Another approach is to use ELMAH which will take care of this so that you shouldn't worry about logging. Yet another approach consists in removing any HandleError global filters from Global.asax and subscribe for the Application_Error which is more general than HandleError as it will intercept also exceptions that happen outside of the MVC pipeline. Here's an example of such handling.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I have thought about using ELMAH, but I haven't really dug into it yet. I guess my question really is more along the lines of 'Is overriding HandleError incorrect?' and/or 'Is there a way to get that error detail on the server side, using the MVC core capabilities?' Thanks for your feedback. – Glenn Ferrie Jul 08 '11 at 14:28
  • 1
    i'll accept your answer, although its not what I was looking for. my question was how to appropriately use the core MVC components and your answer was -- use a custom tool. – Glenn Ferrie Jul 11 '11 at 16:11