Any developer worth their salt knows that exception handling is of high importance during application development. Now with the burgeoning business of web and mobile application development, it is especially significant that errors are handled effectively without breaking the system. It is also necessary to display the relevant error messages or exception messages ensuring that no internal details are revealed when the application halts during exception. Details of all such incidents must be logged and recorded for investigation. Companies looking to hire ASP.NET programmer can also ask a few questions to potential candidates about handling exception errors to validate their knowledge.
There are many ways of handling exceptions in ASP.NET MVC but what does best practice recommend? Let’s take a look at some of the scenarios and the preferred way of handling errors.
1. Try/Catch block: One of the simplest methods is to use the try catch block where you want to wrap all your code in the action as demonstrated below. Catch is a C# feature and you can do as you please with your exceptions: log them, email them to admin, or just swallow them.
public ActionResult SomeError()
{
try
{}
catch(Exception ex)
{return View("Error");}
}{
// Add your code here
}
catch
{
// Exception Handling code
}
However, there are limitations to this approach, one of the main problems being the limitation to single Action. It is useful in some scenarios but in some others we need to use more sophisticated methods.
2. OnException method: Try Catch method is useful in some situations but it is not preferred because you need to find out all the possible scenarios in the project where an exception can be thrown. This is not a sensible way of writing exceptions and you have to rewrite the error handling code several times. The better option is to write a reusable code using base class at the controller level.
The OnException method is usually invoked if an action method from the controller throws an exception. Unlike the HandleErrorAttribute it catches 404 and other HTTP error codes and it doesn't need customErrors to be turned on. You can override the “OnException” event of the controller and set the “Result” to the view name. This view is called when error occurs in this controller. For instance, you can see in the following code that we have set the “Result” to a view name called “Error”.
public class HomeController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
var model = new HandleErrorInfo(filterContext.Exception, "Controller","Action");
filterContext.Result = new ViewResult()
{
ViewName = "Error",
ViewData = new ViewDataDictionary(model)
};
}
This helps to handle exceptions at controller level and also send custom error views to the browser. However this too has limitations:
a. It can only handle controller level exception.
b. Exception response shows HTTP 200 in the error view and also search engines are able to crawl this.
3. HandleError attribute: You can implement the HandleError Attribute to tackle such errors globally. Implementing “HandleError” attribute is a two-step process:
Step 1: You will need to first decorate the action method or the class with “HandleError” attribute.
Step 2: Add the customErrors” tag and point to the “Error” view in the “Web.config” file.
In case you want different error views for different exception types you can decorate action method with multiple “HandleError” attribute point to multiple views as per exception types.
4. Global error handling in MVC: Global error handling is one of the best ways to deal with exceptions at application level. This is however an out of the box feature and can be easily set up using the following steps:
a) Set customErrors errors as On in web.config as
b) Create a common error view (in shared folder with the name error.cshtml) which will be shown in case of error.
c) Ensure we register HandleErrorAttribute in Application_Start (Global.asax) method.
RegisterGlobalFilters(GlobalFilters.Filters);
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
filters.Add(new HandleErrorAttribute());
}
In Summary: Here you could see various possible ways of handling exceptions. There are many more ways and you can explore this subject in detail. It is important to remember that no single approach is always going to be perfect or ideal. Often what works well is a combination of approaches based on the requirement. Do you prefer any particular method for exception handling? Please share in the comments below.