21
NovException or Error Handling and Logging in MVC4
Exception or Error Handling: An Overview
Error handling is the main concern in any application, whether it is a web application or a desktop application. Usually, we catch the exception and log its details to a database or text, XML file and also display a user-friendly message to the end-user in place of the error. In this MVC Tutorial, we will explore more about theException or Error Handling which will include the HandleError filter in mvc, customize error handling in mvc4, how to handle and log errors in mvc, and log exceptions in mvc. Consider our ASP.NET MVC Course for a better understanding of all MVC core concepts.
Asp.Net MVC has some built-in exception filters. HandleError
is the default built-in exception filter. Let's see how to use this filter within your application.
HandleError Attribute
The HandleErrorAttribute filter works only when custom errors are enabled in the Web.config file of your application. You can enable custom errors by adding a customErrors
attribute inside the <system.web>
node, as shown below:
</system.web>
...
<customErrors mode="On" defaultRedirect="Error.htm"/>
</system.web>
HandleError Attribute can be used to handle errors at Action Method
level, Controller
level and Global
level.
HandleError Attribute at Action Method Level
Simply put this attribute to the action method tells MVC how to react when an exception occurs.
[HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
public ActionResult Index(int id)
{
var db = new MyDataContext();
return View("Index", db.Categories.Single(x => x.Id == id));
}
In the above example when a database exception (System.Data.DataException) occurs during the execution of the Index action, MVC will display the DatabaseError
view.
HandleError Attribute at Controller Level
Simply put this attribute to the controller tells MVC how to react when an exception occurs within the action methods of this controller.
[HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
public class HomeController : Controller
{
/* Controller Actions with HandleError applied to them */
}
In the above example when a database exception (System.Data.DataException) occurs during the execution of the controller's any action method, MVC will display the DatabaseError
view.
HandleError Attribute at Global Level
You can also apply the HandleError Attribute for the entire application by registering it as a global error handler. For registering a global error handler, open the FilterConfig.cs file within the App_Start folder to find the RegisterGlobalFilters method.
By default, the ASP.NET MVC template has already registered a global HandleErrorAttribute to the GlobalFilterCollection for your application. Here you can also add your own custom filter to the global filter collection as well.
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(System.Data.DataException),
View = "DatabaseError"
});
filters.Add(new HandleErrorAttribute()); //by default added
}
Note
Always remember, by default, global filters are executed in their registered order. so register error filters for specific exception types before any other.
You can also set the order of execution of these filters by giving a number of values to each. The above-registered filters can be re-written as:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute(),2); //by default added
filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(System.Data.DataException),
View = "DatabaseError"
},1);
}
Now, all the filters will be executed in the number sequence.
Limitation of HandleError Attribute
It has no support to log the exceptions since it suppresses the error once it is handled.
It only catches 500 HTTP errors and doesn't catch other HTTP errors like 404,401 etc.
It doesn't catch the errors that occur outside the controllers like errors that occur in the model.
It returns an error view even if an error occurred in AJAX calls that is not useful on the client side. It would be great to return a piece of JSON in AJAX exceptions.
Extending HandleError Filter for logging and handling more errors
You can also make your custom error filter by extending HandleError
the filter. Let's see how to extend this filter to log the exceptions and return a JSON object for AJAX calls.
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
// if the request is AJAX return JSON else view.
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult
{
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary(model),
TempData = filterContext.Controller.TempData
};
}
// log the error by using your own method
LogError(filterContext.Exception.Message, filterContext.Exception);
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Conclusion
So in this article, we have learned about the Exception or Error Handling and Logging in MVC4. I hope you enjoyed learning these concepts while programming with Asp.Net. Feel free to ask any questions from your side. Your valuable feedback or comments about this article are always welcome. Level up your career in MVC with our ASP.Net Core Certification.