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"; } }