Exception handlinf in MVC

http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc

  1. Simply Try…Catch approach in the ActionMethod.

Limitation:

Problem with the above approach is we cannot reuse the exception handling logic across multiple action methods.

2. Override OnException method in controller

protected override void OnException(ExceptionContext filterContext){   Exception e = filterContext.Exception;    //Log Exception here   filterContext.ExceptionHandled=true;   filterContext.Result = new ViewResult()   {       ViewName = “Error”   };}

Advantage

Now we can share error handling logic across all the actions in a controller

Limitation:

Problem with the above approach is we cannot reuse the exception handling logic across multiple controllers. That where global error handling comes to picture.

Global level Exception Handling

Step 1

In Web.Config simply enable custom error as follows and execute our application.

<customerrors mode=”On” />

That’s enough. Now if any exception occurs we get one error message on webpage. How we get by turning Customeerrors simply ON in the config? We have not specified the error page (view) name anywhere, still in response we get error view whenever error occurs. Let’s understand how?

FilterConfig class

public class FilterConfig{    public static void RegisterGlobalFilters(GlobalFilterCollection filters)   {       filters.Add(new HandleErrorAttribute());   } }

As you can see HandleErrorAttrubute is added to global filter collection.

Where RegisterGlobalFilters method is invoked?

In Global.asax file in Applicaion_Start RegisterGlobalFilters method is invoked.

What it does?

It handles all the exceptions raised by all action methods in all the controllers and return error view present inside shared folder.

HandleError at controller level?

  1. Remove the code written in FilterConfig class
  2. Add HandleErrorAttribute to Controller class as follows,

Now errors raised by all action methods present inside TestingController method will be handled. Other exceptions will be considered as unhandled exceptions.

HandleError at Action level

Add HandleErrorAttribute to Action method as follows,

Displaying error detail in Error view

For that we will make our error view strongly typed view of model System.Web.Mvc.HandleErrorInfo and then as usual using @Model keyword we can access the members. One of the member is Exception object.

 

@model System.web.mvc.HandleErrorInfo

 

<h2>Exception details</h2>

<p>

Controller: @Model.ControllerName <br>

Action: @Model.ActionName

Exception: @Model.Exception

</p>

 

Limitations of HandleErrorAttribute

  1. Error won’t get logged anywhere.
  2. Exceptions raised outside controllers will not be handled. Example- exception raised because of invalid url won’t be handled.
  3. Exception Handling based on scenario is not possible. Example – So one error page when request comes via ajax and different one when comes via normal request.

Advantages of extending Handle Error Attribute

  1. Now we can log errors.
  2. More control over exception handling. Now we have full control over exception handling code so we can simply check whether it’s an Ajax request or normal request and proceed accordingly.

Extending Handle Error Attribute

All the exception filters implements the IExceptionFilter interface. Below shows the definition of this interface. The IExceptionFilter contains a single method called OnException which will be called whenever an exception occurs. The ExceptionContext parameter which derives from ControllerContext provides access to the controller, route data and HttpContext.

1

2

3

4

public interface IExceptionFilter

{

void OnException(ExceptionContext filterContext);

}

The HandleErrorAttribute is the default implementation of the IExceptionFilter. When you create a MVC application you will see the HandleErrorAttribute is added to the GlobalFiltersCollection in the Global.asax.cs.

What the HandleError filter does?

The HandleError filter handles the exceptions that are raised by the controller actions, filters and views, it returns a custom view named Error which is placed in the Shared folder. Inbuilt custom error view contains nothing other than a simple text message. The Layout property is set to null so that the Error view doesn’t inherits the application’s style. The HandleError filter works only if the <customErrors> section is turned on in web.config.

To extend HandleError

public class CustomHandleErrorAttribute : HandleErrorAttribute

{ public override void OnException(ExceptionContext filterContext)

{ if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)

{   return; …………..

}

“Resource cannot be found” Exception

This is the one which cannot be handled by neither HandleErroAttribute nor CustomHandleErrorAttribute. But we can follow the traditional web.config approach as follows.

<customerrors mode=”On”>  <error statuscode=”404″ redirect=”~/Testing/NoPageFound”></error></customerrors>

How Global level HandleErrorAttribute is different from Application_Error?

Application_Error is an application level event, we define in the global.asax file. It will be executed whenever there is an unhandled exception in the application. If this is the point, why we won’t use Application_Error always?

Here are the advantages of HandleError over Application_Error,

  1. With HandleErrorAttribute we get more control over exception handling. HandleError allow us to handle error differently for different controllers and actions easily where in Application_Error to get this feature we take the help of switch loop. Also we can show different views for different controller actions.
  2. Once you are into Application_Error you are out of MVC and you will lose ControllerContext and then we cannot do much things which will easily possible with HandleError.
  3. The important problem we face in the Application_Error event is, once the program execution reaches this point then we are out of MVC context and because of that we can miss some context information related to the exception.

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 added10.

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s