Patrick Patrick - 2 months ago 21
C# Question

Handle Error with NLog and Try Catch

I log errors in my Actions using NLog to store errors with additional information, for example:

using NLog;

private static Logger _logger = LogManager.GetCurrentClassLogger();

public virtual ActionResult Edit(Client client)
{
try
{
// FORCE ERROR
var x = 0;

x /= x;

return RedirectToAction(MVC.Client.Index());
}
catch (Exception e)
{
_logger.Error("[Error in ClientController.Edit - id: " + client.Id + " - Error: " + e.Message + "]");
}
}


And I have Error handling configured in Web.config:

<customErrors mode="On" />


But I don't get redirected to the Error.cshtml when I execute the Action (the page remains in the same place), why?

Can I use Elmah to do the same thing? (logging additional information like client Id)

Answer

First of all, most people solve this error by not catching the exception. This way, the exception propagates to ASP.NET, which displays a "500 Internal Error" webpage, and all the pertinent information is logged.

  • If your server is configured for production, the error page will just say "an error occurred, details were logged."

  • If the server is configured for development, then you will get the famous yellow page with the exception type, the message, and the stack trace.

Swallowing the exception and manually redirecting to an error page is a bad practice because it hides errors. There are tools that examine your logs and give you nice statistics, for example about percentages of successful/failed requests, and these won't work any more.

So, not swallowing the exception is what people do, and at the very least, it solves your problem.


Now, I find this very clunky, because I do not like manually looking for the source files mentioned in the yellow page and manually going to the mentioned line numbers. I practically have no use for the yellow page, it might just as well just say "an error occurred, cry me a river, nah-nah-nah." I don't read the yellow page.

Instead, I do like to log exceptions on my own, and I have my logger begin each line with full-path-to-source-filename(line):, so that every line on the debug log in visual studio is clickable, and clicking on a line automatically opens up the right source file, and scrolls to the exact line that issued the log message. If you want this luxury, then go ahead and catch the exception, but right after logging the exception you have to rethrow it, so that things can follow their normal course.

Amendment

Here is some information that was added in comments:

So, you can do the following:

try
{
   ...
}
catch (Exception e)
{
    log( "information" );
    throw; //special syntax which preserves original stack trace
}

Or

try
{
   ...
}
catch (Exception e)
{
    throw new Exception( "information", e ); //also preserves original stack trace
}

Do not do this: catch( Exception e ) { log( "information" ); throw e; } because it loses the original stack trace information of e.