MVC Error Handle with custom error Messages

Patrick

I'm building a new Web Application using MVC5 and I need the followings:

  1. Catch errors
  2. Log the details in a file
  3. Send them by email
  4. Add to the detail custom information (for example the Id of the record I'm trying to read)
  5. Return to the view custom messages to the user

I have found a lot of information regarding the HandleErrorAttribute but none of them allow to add specific details to the error, also I have found information saying that the try catch aproach is too heavy for the server.

For now, I have:

Controller:

public partial class HomeController : Controller
{
    private static Logger logger = LogManager.GetCurrentClassLogger();

    public virtual ActionResult Index()
    {
        try
        {
            return View();
        }
        catch (Exception e)
        {
            logger.Error("Error in Index: " + e);
            return MVC.Error.Index("Error in Home Controller");
        }
    }
}

I have found this Extended HandleErrorAttribute that seems complete but don't do everything I need:

private bool IsAjax(ExceptionContext filterContext)
{
    return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}

public override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
    {
        return;
    }


    // if the request is AJAX return JSON else view.
    if (IsAjax(filterContext))
    {
        //Because its a exception raised after ajax invocation
        //Lets return Json
        filterContext.Result = new JsonResult(){Data=filterContext.Exception.Message,
            JsonRequestBehavior=JsonRequestBehavior.AllowGet};

        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();    
    }
    else
    {
        //Normal Exception
        //So let it handle by its default ways.
        base.OnException(filterContext);

    }

    // Write error logging code here if you wish.

    //if want to get different of the request
    //var currentController = (string)filterContext.RouteData.Values["controller"];
    //var currentActionName = (string)filterContext.RouteData.Values["action"];
}
Jenish Rabadiya

Your requirement best fit with Elmah. Very good plugin for logging errors.

ELMAH stands for Error Logging Modules And Handlers

ELMAH provides such a high degree of plugability that even Installation of ELMAH does not require compilation of your application.

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

Reference from the blog of SCOTT HANSELMAN

Just need to copy binary of ELMAH to bin folder of your application and edit web.config file. That's it!

you need to add following to your web.config and make some other changes described in the following links.

<sectionGroup name="elmah">
  <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
  <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
  <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
  <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>

For example to set up mail account.

<configuration>
    <configSections>
        <sectionGroup name="elmah">
            <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/>
            <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah"/>
            <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
        </sectionGroup>
    </configSections>
    <elmah>
    <errorMail from="[email protected]" to="[email protected]"
       subject="Application Exception" async="false"
       smtpPort="25" smtpServer="***"
       userName="***" password="***">
    </errorMail>
    </elmah>
<system.web>        
    <customErrors mode="RemoteOnly" defaultRedirect="CustomError.aspx">
        <error statusCode="403" redirect="NotAuthorized.aspx" />
        <!--<error statusCode="404" redirect="FileNotFound.htm" />-->
    </customErrors>
    <httpHandlers>
        <remove verb="*" path="*.asmx"/>
        <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
        <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
    <httpModules>
        <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
        <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
    </httpModules>
</system.web>
</configuration>

Here is some good reference link (that contains detailed reference to installation of ELMAH to your project) for your reference.

https://msdn.microsoft.com/en-us/library/aa479332.aspx

https://code.google.com/p/elmah/wiki/MVC

Update

Add to the detail custom information (for example the Id of the record I'm trying to read)

You can build your own custom exception that derives from Exception.

public class MyException : Exception
{
    public MyException(string message, Exception ex) : base(ex.Message, ex)
    {

    }
}

and then using it like

public virtual ActionResult Index()
{
    try
    {
        return View();
    }
    catch (Exception e)
    {
        throw new MyException("detailed exception", e);
    }
}

in this way main exception would be wrapped inside the myexception and you can add your detailed custom exception message.

Return to the view custom messages to the user

You just need to add

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

and add Error.cshtml inside the ~/View/Shared folder Then whenever exception is encountered it will find for Error.cshtml inside view/shared folder and render the content. so you can render there your custom message.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

HotTag

Archive