Skip to content

Instantly share code, notes, and snippets.

@jmyrland
Created March 3, 2015 09:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmyrland/26861df725d17a997db0 to your computer and use it in GitHub Desktop.
Save jmyrland/26861df725d17a997db0 to your computer and use it in GitHub Desktop.
Simple exception logging for ASP.NET MVC

Simple exception logging for ASP.NET MVC

  1. Add the ExceptionUtility.cs and ErrorHandlerAttribute.cs
  2. Add the ErrorHandlerAttribute to your base controller to start logging errors. Like:
  [ErrorHandler]
  public class BaseController : Controller
  {
      // ...
  }

Based on the request type, the error is either reported as JSON or a norman HTML response (given a view).

Example view Error.cshtml:

@model dynamic

<div class="alert alert-danger" role="alert">
    <strong>Oops.. an error occured with the message "@Model.error"</strong>
    
    <p>The error has been logged with the ID: <span class="label label-primary">@Model.token</span></p>
</div>

The error logs is found in your project root, under /App_Data/ErrorLogs/.

Features

  • A token is generated for each error, for easy searchability.
  • Errors is gathered in a single file for each day, separated by year and month folders.

This code is based of this example.

using System.Collections.Generic;
using System.Dynamic;
using System.Web.Mvc;
namespace Example.Web.ErrorHandling
{
public class ErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
// Log the exception and notify system operators
var token = ExceptionUtility.LogException(filterContext.Exception, filterContext.HttpContext.Request.RawUrl);
ExceptionUtility.NotifySystemOps(exception);
var exceptionData = new
{
success = false,
token = token,
error = exception.Message
};
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = exceptionData,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
var viewResult = new ViewResult()
{
ViewName = "~/Views/Error/Error.cshtml"
};
viewResult.ViewData.Model = ObjectToExpando(exceptionData);
filterContext.Result = viewResult;
}
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.StatusCode = 500;
}
private static ExpandoObject ObjectToExpando(object anonymousObject)
{
IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
}
}
using System;
using System.IO;
using System.Web;
// Create our own utility for exceptions
namespace Example.Web.ErrorHandling
{
public static class ExceptionUtility
{
// Log an Exception
public static string LogException(Exception exc, string source)
{
// Generate token for easy searchability
var token = Guid.NewGuid().ToString();
// Get the absolute path to the log file
var logPath = string.Format("~/App_Data/ErrorLogs/{0:yyyy}/{0:MMMM}", DateTime.Now);
logPath = HttpContext.Current.Server.MapPath(logPath);
// Create the log folders, if not existing
if (!Directory.Exists(logPath))
{
Directory.CreateDirectory(logPath);
}
// Get the absolute log file path
var logFile = string.Format("{0}/{1:yyyyMMdd}-ErrorLog.txt", logPath, DateTime.Now);
// Open the log file for append and write the log
using (StreamWriter sw = File.AppendText(logFile))
{
sw.WriteLine("********** {0} : {1} **********", token, DateTime.Now);
sw.WriteLine("Source: " + source);
if (exc.InnerException != null)
{
sw.Write("Inner Exception Type: ");
sw.WriteLine(exc.InnerException.GetType().ToString());
sw.Write("Inner Exception: ");
sw.WriteLine(exc.InnerException.Message);
sw.Write("Inner Source: ");
sw.WriteLine(exc.InnerException.Source);
if (exc.InnerException.StackTrace != null)
{
sw.WriteLine("Inner Stack Trace: ");
sw.WriteLine(exc.InnerException.StackTrace);
}
}
sw.Write("Exception Type: ");
sw.WriteLine(exc.GetType().ToString());
sw.WriteLine("Exception: " + exc.Message);
sw.WriteLine("Stack Trace: ");
if (exc.StackTrace != null)
{
sw.WriteLine(exc.StackTrace);
sw.WriteLine();
}
}
return token;
}
// Notify System Operators about an exception
public static void NotifySystemOps(Exception exc)
{
// Include code for notifying IT system operators
}
}
}
@opensourcer-15
Copy link

Great article,

I am new to MVC and i was able to implement this sample but how do i test it?

@franks1
Copy link

franks1 commented Jun 30, 2020

Good example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment