3

I've been following this guide for the HandleError attribute: blogs.msdn.com which I use like this (AccountController):

[HandleError(View="ErasErrorPage")]
        public ActionResult Index()
        {
            ViewBag.admins = _accountMapper.GetAdmins(false);
            ViewBag.members = _accountMapper.GetMembers(false);
            ViewBag.Countries = _countryMapper.GetCountries();

            return View();
        }

This code throws an exception because _accountMapper.GetAdmins(false) fails because of a System.Data.EntityException.

I've put the ErasErrorPage view in my Shared folder and I've added <customErrors mode="On"/> but the ErasErrorPage does not show up. All I get when the error occurs is a yellow screen of death saying:

Error Obviously, setting the mode to "Off" or "RemoteOnly" doesn't solve the problem.

Anyone has an idea why this doesn't work?


EDIT

If I surf directly to http://localhost:3527/Account/Index, I do get the correct ErasErrorPage, but I don't want that. I want the website to automaticly redirect to that page when an exception is thrown somewhere. Is this possible?


EDIT2

I've put the [HandleError(View="ErasErrorPage")] attribute right before every single Public ActionResult methodName() { ... } method, and I still get the Yellow Screen of Death saying I need to change the mode to "Off" or "RemoteOnly"...

Matthias
  • 12,704
  • 13
  • 35
  • 56
  • This is a very old question but for people stumbling across it. You MUST have customErrors="On", and the exception must be generating a 500 class error, throw a 403 and it's not going to fire, it wont handle child actions or exceptions that have already been handled and the exception must derive from System.Exception, no natives. An easy way to test this would have been to simply remove the View property, check that it is at least firing off to the default Error page. If it is, you know its a path error etc to your custom view. – rism May 23 '15 at 12:43

3 Answers3

3

Make sure that the ErasErrorPage view doesn't itself throw an exception. Here are the steps I did and which worked fine for me:

  1. Create a new ASP.NET MVC 3 Project using the default Visual Studio wizard
  2. Add ~/Views/Shared/ErasErrorPage.cshtml with the following content:

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>ErasErrorPage</title>
    </head>
    <body>
        <div>
            OOPS
        </div>
    </body>
    </html>
    
  3. Modify HomeContoller to look like this:

    public class HomeController : Controller
    {
        [HandleError(View = "ErasErrorPage")]
        public ActionResult Index()
        {
            throw new Exception("oops");
        }
    }
    
  4. In web.config put:

    <customErrors mode="On" />
    
  5. Navigate to /Home/Index => the custom error page is displayed as expected

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • @Matthias, you have decorated only the Index action with this attribute. If you want to use this custom error page for all actions you could either write a custom handle error attribute and register it as global filter or have a base controller which all your controllers derive from and have this controller decorated. – Darin Dimitrov May 10 '11 at 09:47
  • @Darin: Yes, I think that might work then... Could you give an example of how to do it then? Because wouldn't I still need to add [CustomError] attributes above all the ActionResult methods? – Matthias May 10 '11 at 09:50
  • @Mathias, no you would do this in the `RegisterGlobalFilters` method of `Global.asax`. This will register it as a global filter and thus be automatically applied to all actions in your application. So simply replace the default with the following line: `filters.Add(new HandleErrorAttribute() { View = "ErasErrorPage" });` and you will be good to go. No longer necessary to decorate manually your controller actions with the `[HandleError(View = "ErasErrorPage")]` attribute. – Darin Dimitrov May 10 '11 at 09:52
  • No, sorry... I still get the same YSOD. – Matthias May 10 '11 at 12:00
  • @Matthias, what does the `ErasErrorPage.cshtml` contain? Did you try with an very simple template as the one I showed in my answer? – Darin Dimitrov May 10 '11 at 12:09
  • For testing purposes it currently contains a simple

    Test Error

    Nothing more
    – Matthias May 10 '11 at 12:18
  • @Mathias, does it contain `@{ Layout = null; }` as well? – Darin Dimitrov May 10 '11 at 12:22
  • Yes, it does contain that. But with, or without. It fails – Matthias May 10 '11 at 12:31
  • Has this problem been solved ? I am facing the same issue. Looks like some environments it works and for other it doesnt... – user20358 Jun 27 '12 at 19:45
  • @user20358, the example I have shown here works perfectly fine. It's been tested under VS built-in server and IIS. If it doesn't work for you, it means that you probably are doing something different. – Darin Dimitrov Jun 27 '12 at 19:48
3

Since this doesn't work at all, I've found a very good alternative:

Custom error pages on asp.net MVC3

I also found out why it failed:

We were trying to connect to the database before we tried rendering views. The HandleError attribute won't even be triggered by that (I think). The method above does do that. It handles any exception, anywhere.

Community
  • 1
  • 1
Matthias
  • 12,704
  • 13
  • 35
  • 56
1

It does work, I have a BaseController with the attribute [HandleError(View = "Error")] and an Error view in Shared with a dynamic model (should be HandleErrorInfo) and at the Index action in the HomeController I am throwing an exception:

throw new Exception("Test exception");

The error view is then rendered and displays the correct information.

ErrorView:

<div class="errorMessage">
    <h1 class="errorHeader">@Model.Exception.GetType().Name</h1>
    <cite class="errorAction">thrown in @Model.ControllerName @Model.ActionName</cite>
    <p class="errorMessage">thrown in @Model.Message</p>
</div>
bn.
  • 7,739
  • 7
  • 39
  • 54
gonace
  • 27
  • 2
  • 11
  • `This comment was a suggested edit from someone:` Edit because I can't comment: I can verify that this works for me as well, but only if I set `Response.StatusCode = (int)HttpStatusCode.OK;` in the custom error view. Otherwise, even though the view in the ErrorView gets generated, the response is replaced with a generic 500 error page. – Jeremy Thompson Dec 13 '12 at 05:47