ASP.NET MVC Custom Errors With the HandleError Attribute

Handling exceptions in ASP.NET MVC is quite easy once you get to know the details surrounding the HandleError attribute. You can specify that a controller or a specific Action will handle errors and you can even choose which View to show based on the exception being thrown. Scott Guthrie wrote about this.

What he didn’t tell us, is that there are some prerequisites for it to work as expected. First of all, you need to enable custom errors in the application web.config file:

Second, the order that you put the HandleError attributes will affect which View will actualy gonna be rendered at the end. I was trying to render a custom view based on an InvalidOperationException being throw on my action. The code looked like this:

<span class="lnum">   1:  </span>[HandleError]

<span class="lnum">   2:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> HomeController : QuavioController

<span class="lnum">   3:  </span>{

<span class="lnum">   4:  </span>        [HandleError(ExceptionType = <span class="kwrd">typeof</span>(InvalidOperationException), View = <span class="str">"InvalidOpJoinRoom"</span>)]

<span class="lnum">   5:  </span>        <span class="kwrd">public</span> ActionResult JoinRoom()

<span class="lnum">   6:  </span>        {

<span class="lnum">   7:  </span>             <span class="kwrd">throw</span> <span class="kwrd">new</span> InvalidOperationException();

<span class="lnum">   8:  </span>        }

<span class="lnum">   9:  </span>}

What happened is that the JoinRoom was returning the shared Error View, instead of the InvalidOpJoinRoom View. This happens because the HomeController contains a HandleError attribute (line 1), which overrides the JoinRoom’s HandleError behavior (line 4), which should return the InvalidOpJoinRoom View.

The fix is very simple: Remove the HandleError atribute from the controller and let the actual actions define the proper error handling behavior.

Conclusion: Be aware that multiple HandleError attributes in a controller may alter the order which View evaluation is executed and then causing the final View not to be the view you were actually expecting.