Pregunta

I've seen a number of posts and articles but am not able to see the solution crisply.

I've installed Elmah.MVC via NuGet and have commented out this line from FilterConfig.cs:

//filters.Add(new HandleErrorAttribute());

So that Elmah would pick up the errors.

It works when I provide an invalid action name and I get a yellow page as well as an email.

I want to know about two other types of errors that my code may generate... how are we supposed to handle them:

1.E.g. if my repository or manager (business logic) layer throws an exception when trying to access database or send an email etc.

a. Is the correct way to NOT implement any kind of try catch in Controllers (or anywhere else for that matter) and let Elmah take care of exceptions?

b. If so, and if it shows a yellow error page, how can we show a view of our own liking?

2.If my view contains ajax calls, e.g. via jqgrid, and behind the scenes there are errors, I've noticed they also get picked up properly by Elmah. But how do I show some kind of an error message to the user as well?

Thanks

¿Fue útil?

Solución

Here is what I did:

In controller, I placed try catch:

        try
        {
            //model = getmodelfromdb();

            return View("MyView", model);
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
            return View("../Error/ShowException", ex);
        }

For custom view for 404, I did this in global.asax:

    protected void Application_OnError( )
    {
        var exception = Server.GetLastError( );

        Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

        Helper.SetSessionValue(SessionKeys.EXCEPTION, exception);

        Response.Redirect( "~/Error/ShowException");
    }

For jqgrid, I did this in my controller:

    [HttpPost]
    public ActionResult ListRecords( int page , DateTime? fromdate , DateTime? todate)
    {

               try
               {
                 var list = FetchListFromDB();

            var result = new
                {
                    total = Math.Ceiling(list.Count / (decimal)Helper.PAGE_SIZE),
                    page = page, //--- current page
                    records = list.Count, //--- total items
                    rows = list.List.Select(x => new
                    {
                        id = x.EntityID,
                        cell = new string[] 
                {
        x.Property1,
                    x.Property2
                }
                    }).ToArray()
                };


            return Json(result, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {

            var result = new
            {
                errorMessage = "An unexpected error occurred while fetching data. An automatic email has been generated for the support team who will address this issue shortly. Details: " + ex.Message,
                records = 0
            };

            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

            return Json(result, JsonRequestBehavior.AllowGet);
        }

And this in the View (in the jqgrid definition):

        loadComplete:function(data)
        {
            if (data.errorMessage)
            {
                alert(data.errorMessage);
            }
        },

In a general ajax scenario:

        success: function(data)
        {
            if (data.errorMessage)
            {
                alert(data.errorMessage);
            }
            else
            {
                           //...
            }
        },

Otros consejos

a. Is the correct way to NOT implement any kind of try catch in Controllers (or anywhere else for that matter) and let Elmah take care of exceptions?

I'd say that Elmah doesn't "take care" of exceptions, it records them. Ideally, you should try to handle the errors - by all means log them, but also add logic to deal with them so that they don't interrupt the user's workflow.

I'd wrap logic in try blocks, and in the catch use

Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

to record anything that goes wrong. Immediately after that line, however, I'd then do something to try to recover from the exception - catch specific exception types, never just catch (Exception e), and deal with them after logging them. The idea is that you should be reviewing your logs, working out what's causing the exceptions, and improving your program so that it doesn't throw exceptions any more.

To show your own error pages, there's the HandleErrorAttribute, or if you don't want to use that there's also the controller's OnException() method, which is called when a controller action method quits with an exception rather than finishing normally. An ExceptionContext object is passed into that method, so you can use that to get the exception that was thrown and log it, do any cleanup that might be required etc.

I know i'm very late to the party but I stumbled upon this answer while searching something similar form Google.

I don't like using try catch blocks everywhere in my code, especially in web apps. I let Elmah catch everything and log it behind the scenes. Then in the web.config file you can redirect based on the error type...

 <customErrors mode="RemoteOnly" defaultRedirect="~/Error" >
  <error statusCode="500" redirect="~/Error"/>
  <error statusCode="404" redirect="~/NotFound"/>
</customErrors>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top