Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error handling in MVC

I've struggled a couple of days with the error handling in MVC. I still do not have got it right. (I've also read most of the questions here at SO and googled until my fingers bled)

What I want to do:

  1. Use the standard [Authorize] attribute
  2. Redirect all errors to my error controller (including unauthorized)
  3. Have one action per HTTP error in my error controller.

What I do not want to do:

  1. Put the [ErrorHandler] on all of my controllers (can it be used on my base controller)?
  2. Use a custom Authorize attribute.

Actually I could do anything necessary (including the NOT list) as long as I get #1-3 working.

What I've tried:

  1. Using Application_Error
  2. Using Controller.HandleUnknownAction
  3. Using Controller.OnException
  4. Using [ErrorHandler] on my controllers
  5. Turning on/off CustomErrors in web.config

Guess I need a combination of those or maybe something else?

like image 766
jgauffin Avatar asked Feb 03 '11 08:02

jgauffin


People also ask

What is exception handling in MVC?

Summary on MVC Error Handling config <customErrors> and log unhandled exceptions that get called back to your HttpApplication Error method. You can use HandleErrorAttribute or OnException to provide fine-grained control of how you display error type messages to your users.

What is error handling method?

Error handling refers to the response and recovery procedures from error conditions present in a software application. In other words, it is the process comprised of anticipation, detection and resolution of application errors, programming errors or communication errors.

How do you handle error handling?

You can propagate the error from a function to the code that calls that function, handle the error using a do - catch statement, handle the error as an optional value, or assert that the error will not occur.

What are the exception filters in MVC?

Exception filter in MVC provides an ability to handle the exceptions for all the controller methods at a single location. This is by creating a class, which inherits from the FilterAttribute and IExceptionFilter interface.


2 Answers

You could also handle all your error logic in the Application_Error of your Global.asax.cs and then route them dynamically bases on the different HTTP status codes:

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError().GetBaseException();

    var routeData = new RouteData();

    if (ex.GetType() == typeof(HttpException))
    {
        var httpException = (HttpException)ex;

        switch (httpException.GetHttpCode())
        {
            case 401:
                routeData.Values.Add("action", "NotAuthorized");
                break;
            case 403:
                routeData.Values.Add("action", "NotAuthorized");
                break;
            case 404:
                routeData.Values.Add("action", "PageNotFound");
                break;
            default:
                routeData.Values.Add("action", "GeneralError");
                break;
        }
    }
    else
    {
        routeData.Values.Add("action", "GeneralError");
    }

    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("error", ex);

    IController errorController = new ErrorController();
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}

It seems the 401 doesn't throw necessary a HttpException so you want to handle that manually to fit the logic:

protected void Application_EndRequest(object sender, EventArgs e)
{
    if (Context.Response.StatusCode == 401)
    {
        throw new HttpException(401, "You are not authorised");
    }
}

And yes, your controllers inherit the attributes from your base conroller.

like image 146
Martin Buberl Avatar answered Oct 12 '22 00:10

Martin Buberl


You can use a custom filter, just extend ErrorHandlerAttribute and make it aware of your error controller. Than add it as a global filter inside Application_Start:

GlobalFilters.Filters.Add(new CustomAErrorHandlerAttribute());
like image 22
frennky Avatar answered Oct 12 '22 00:10

frennky