Thursday, 30 April 2015

Custom handle Error Attribute - Global

public class CustomHandleErrorAttribute : HandleErrorAttribute
    {
 
        public override void OnException(ExceptionContext filterContext)
        {
            //only for system exceptions like 500 errors
            //this methods redirects the user to Error.cshtml inside views/shared folder
            //in this case Application_Error inside global.asa doesn't get called
            var exceptionCode = new HttpException(null, filterContext.Exception).GetHttpCode();
 
            var currentController = (string)filterContext.RouteData.Values["controller"];
            var currentActionName = (string)filterContext.RouteData.Values["action"];
            var exception = filterContext.Exception;
            var message = exception.Message;
            var innerMessage = exception.InnerException == null ? string.Empty : exception.InnerException.Message;
 
            var isExceptionHandled = filterContext.ExceptionHandled;
            var isCustomErrorEnabled = filterContext.HttpContext.IsCustomErrorEnabled;
 
            /*
            //Keep this disabled for now
            if (filterContext.ExceptionHandled || 
                !filterContext.HttpContext.IsCustomErrorEnabled ||
                exceptionCode != 500)
            {
                return;
            }
             */
 
            // if the request is AJAX return JSON else view.
            if (IsAjaxRequest(filterContext))
            {
                //Because its a exception raised after ajax invocation
                //Lets return Json
                filterContext.Result = new JsonResult
                {
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                    Data = new
                    {
                        error = true,
                        message = filterContext.Exception.Message
                    }
                };
 
 
            }
            else
            {
                //Normal Exception
                //So let it handle by its default ways.
                base.OnException(filterContext);
            }
 
            //DO YOUR ERROR LOGGING HERE 

 
            //get the web.config
            var configuration = WebConfigurationManager.OpenWebConfiguration("~/Web.config");
 
            // Get the section.
            CustomErrorsSection customErrors = (CustomErrorsSection)configuration.GetSection("system.web/customErrors");
 
            //only do this after reading error mode, otherwise, this swallows the exceptions, and you get a generic 500 IIS page,
            //instead of the yellow standard asp.net error page with what the exception is and line numbers and all that good stuff. 
           
            if (((customErrors.Mode == CustomErrorsMode.RemoteOnly && HttpContext.Current.Request.IsLocal == false) == false || customErrors.Mode == CustomErrorsMode.Off) == false)
            {
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.Clear();
                filterContext.HttpContext.Response.StatusCode = 500;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            }
        }
 
        private static bool IsAjaxRequest(ExceptionContext filterContext)
        {
            return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
        }
    }