Reputation: 97
We have a VS2013 solution (originally a VS2012 solution, but that isn't relevant) that contains multiple projects. Some class libraries. Some MVC apps. Some WinForm apps. Some comandline apps. What we want is a class that we can use across all projects to grab unhandled exceptions and log them to a configurable target (the particular app can decide if it wants to log to a flatfile, the event log, or db). The idea being that at start up, the app would call a static method, or instantiate an object and then any unhandled exceptions would just be magically logged for the rest of the application.
I thought this would do the trick (although this first attempt just logs to a flatfile):
public class InfLogger
{
public string LogFile { get; set; }
public InfLogger()
{
System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(ThreadExceptionHandler);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionsHandler);
LogFile = "C:\\Infinedi.log";
}
public void ThreadExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs e)
{
try
{
if (File.Exists(LogFile))
{
File.AppendAllText(LogFile, e.Exception.Message + "\n");
}
else
{
File.WriteAllText(LogFile, e.Exception.Message + "\n");
}
}
catch (Exception ex)
{
}
}
public void UnhandledExceptionsHandler(object sender, UnhandledExceptionEventArgs e)
{
try
{
if (File.Exists(LogFile))
{
File.AppendAllText(LogFile, (e.ExceptionObject as Exception).Message + "\n");
}
else
{
File.WriteAllText(LogFile, (e.ExceptionObject as Exception).Message + "\n");
}
}
catch (Exception ex)
{
}
}
}
}
but no joy.
In a MVC app that I'm using to try and test it, I instantiate the InfLogger object, and then purposefully create an array index out of range unhandled exception. But the logger doesn't fire either of the event handlers. :(
Any suggestion on how to accomplish this?
I've done some research and this does in fact work for console apps and winforms. But just not MVC. Hmmm... Not sure why. But there is a new issue that I have found. Here is where the code is being used.
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
InfLogger logger = new InfLogger();
int[] a = { 0, 1, 2 };
int y = a[6];
}
}
}
And the logger does catch the exception. But the execution just hangs on the line: int y = a[6]. It just keeps executing that line, throwing the exception, catching the unhandled exception over and over. So now I need to know how to get execution to actually move past the line that throws the exception.
Upvotes: 0
Views: 627
Reputation: 9726
I call a method in the Program.cs file to set an un-handled exception method. Here is the full explanation of Application.SetUnhandledExceptionMode Method at MSDN.
// ....
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
SetUnhandledExceptionHandler();
// ...
#region -- SetUnhandledExceptionsHandler() Method --
/// <summary>
/// Causes all unhandled exceptions to be handled by the application.
/// This will not prevent the application from being forced to close, but
/// does give a chance to log the error.
/// </summary>
public static void SetUnhandledExceptionHandler()
{
// Add an exception handler for all UI thread exceptions
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to
// Go through this handler
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
#endregion
Upvotes: 1