A feature of my nice WPF application is to log exceptions that bring it down when running standalone. Of course this never happens but still, if such an event occurs I want to understand the cause. Why exceptions in plural? Because an exception might have an InnerException and this InnerException might have another InnerException and so forth.
I use NLog as logging framework. Nice and slick. Here is my really simple configuration:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File" fileName="log.txt" layout="${longdate}:${message} ${exception:format=message,stacktrace:separator=*}" />
<target name="ds" xsi:type="Debugger"/>
</targets>
<rules>
<logger name="*" writeTo="file" minLevel="Warn"/>
<logger name="*" writeTo="ds" />
</rules>
</nlog>
Basically I log exceptions to log.txt file (as well as pretty much everything to debugger’s output). The layout to write the exception is this: layout="${longdate}:${message} ${exception:format=message,stacktrace:separator=*}". It is a pretty much standard NLog’s format for exceptions. However, the problem with it is that it won’t log InnerExceptions at all.
Hence I need to use the following code:
private bool showingFatal;
private void Application_DispatcherUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
if (showingFatal)
{
e.Handled = true;
return;
}
showingFatal = true;
logger.Error(LogCategory.Engine, "Fatal exception start ********************** ");
try
{
int level = 0;
Exception ex = e.Exception;
while (ex != null)
{
logger.Error(LogCategory.Engine,
string.Format("Fatal exception level {0}: ", level++), ex);
ex = ex.InnerException;
}
}
finally
{
logger.Error(LogCategory.Engine, "Fatal exception end ********************** ");
}
Shutdown();
}
I use the flag showingFatal to prevent duplicate entry into the method (not sure why it happens but it happens) and a loop to log all, really all, exceptions and callstacks there are.
This way I have a good information about the exception that caused the crash. If it happens someday…