views:

3691

answers:

6

In two different application, one a custom the other the sample MVC application you get with a new VS2008 MVC project, [HandleError] is not catching exceptions.

In the sample application I have:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        throw new Exception();
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

which is just the default controller with an exception being thrown for testing.

But it doesn't work. Instead of going to the default error.aspx page it shows the debug information in the browser.

The problem first cropped up in a custom application I'm working on which led me to test it with the sample application. Thinking it had something to do with changes I made in the custom application, I left the sample application completely unchanged with the exception (yuck) of the throw in the index method.

I'm stumped. What am I missing?

+21  A: 

In Web.config, change customErrors:

<system.web>
  <customErrors mode="On">
  </customErrors>

If mode is either Off or RemoteOnly, then you will see the yellow screen of death instead of the custom error page. The reasoning is that developers usually want the more detailed information on the yellow screen of death.

Craig Stuntz
That did it. Thank you.
I did this and it did not work. What I've discovered is that in an MVC2 applciation there are more than one Web.config files in the default template. You need to apply the customErrors tag into the root-most Web.config in your solution.
Mike
@Mike, that's true of all MVC versions.
Craig Stuntz
+1  A: 

i tried the same exact thing and making modifications to the web.config does not work. anybody else tried this?

Me too! Tried building in release mode, set customErrors to On and still get the yellow screen
Perhentian
As Simon said - I'd check your error view for errors, and the master page if you're using one. The [HandleError] attribute might be working but another exception is thrown from the view itself.
Luke Sampson
+7  A: 

Important: Be careful that your error page itself does not have an error on it!

If it does you'll end up with that ASP.NET custom error page and end up going round in circles and tearing your hair out.

Also with respect to 'customErrors' being ON or OFF there are several contributing factors to whether or not the friendly error page (your Errors.aspx) page will be shown or not.

See this blog (except below)

HttpContext.IsCustomErrorEnabled - looks at three different sources

  1. The web.config's <deployment> section's retail property. This is a useful property to set when deploying your application to a production server. This overrides any other settings for custom errors.
  2. The web.config's <customErrors> section's mode property. This setting indicates whether custom errors are enabled at all, and if so whether they are enabled only for remote requests.
  3. The HttpRequest object's IsLocal property. If custom errors are enabled only for remote requests, you need to know whether the request is from a remote computer.

The idea here is that you can have 'customErrors' turned OFF during development - when you do want to see the errors, and then enable it for production only.

This MSDN article discusses the attribute further.

Simon_Weaver
+5  A: 

Another reason for this problem may be ,

In Template MVC Application (generated by VS2008 / VS2008 Express) , Error.aspx (generated by VS) uses Master Page.

If Master Page access any ViewData it will throw null reference Exception , then the error.aspx won't be shown.

Use this Simple code as your Error.aspx , it will solve the problem, (along with CustomErrors=On )

<%@ Page Language="C#"  Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<%= Model.Exception.Message %>
Palani
"If Master Page access any ViewData it will throw null reference Exception" that line brought sanity back to me. Thank You!
Marco M.
A: 

Palani's answer solved this for me (sorry, don't have enough mojo to upvote). I started with a VS-generated application and only partially gutted it before adding my work.

I forgot to clean up the master layout, which tries to render the "boilerplate" login control (<% Html.RenderPartial("LogOnUserControl"); %>). Since I killed the login control earlier, the error page itself was blowing up, so the [HandleError] filter instead fell back to showing the yellow screen of death with the exception.

Alex Beynenson
+1  A: 

I have struggled with this as well and I believe I understand the problem now.

In short the requirements for having [HandleError] work as expected are:

You must enable custom errors in web.config AND you must also specify where your error view is in the <customErrors> tag.

Example:

<customErrors mode="On" defaultRedirect="Error" />

Leaving off the defaultRedirect="Error" part will instead yield a 500 error in the browser--NOT the ASP.NET error page (YSOD).

Also you do not have to be in Release mode. I tested this with a Debug build and it worked fine.

My environment was Visual Studio 2010 using .NET 4 and the standard, "ASP.NET MVC 2 Web Application" project template.

What confused me was the MSDN documentation for the HandleErrorAttribute Class. It doesn't explicitly say you must turn on custom errors in web.config. And I assumed all I needed was the [Handle Error] attribute.

Rick Roth