private static void LogExceptions( Exception ex, ExceptionLog log, bool isParent )
{
// First, attempt to log exception to the database.
try
{
ExceptionLog exceptionLog;
// If this is a recursive call and not the originating exception being logged,
// attempt to clone the initial one, and populate it with Exception Type and Message
// from the inner exception, while retaining the contextual information from where
// the exception originated.
if ( !isParent )
{
exceptionLog = log.Clone( false );
if ( exceptionLog != null )
{
// Populate with inner exception type, message and update whether or not there is another inner exception.
exceptionLog.ExceptionType = ex.GetType().ToString();
exceptionLog.Description = ex.Message;
exceptionLog.Source = ex.Source;
exceptionLog.StackTrace = ex.StackTrace;
exceptionLog.HasInnerException = ex.InnerException != null;
// Ensure EF properly recognizes this as a new record.
exceptionLog.Id = 0;
exceptionLog.Guid = Guid.NewGuid();
exceptionLog.ParentId = log.Id;
}
}
else
{
exceptionLog = log;
}
// The only reason this should happen is if the `log.Clone()` operation failed. Compiler sugar.
if ( exceptionLog == null )
{
return;
}
// Write ExceptionLog record to database.
var rockContext = new Rock.Data.RockContext();
var exceptionLogService = new ExceptionLogService( rockContext );
exceptionLogService.Add( exceptionLog );
rockContext.SaveChanges();
// Recurse if inner exception is found
if ( exceptionLog.HasInnerException.GetValueOrDefault( false ) )
{
LogExceptions( ex.InnerException, exceptionLog, false );
}
if (ex is AggregateException)
{
// if an AggregateException occurs, log the exceptions individually
var aggregateException = ( ex as AggregateException );
foreach ( var innerException in aggregateException.InnerExceptions )
{
LogExceptions( innerException, exceptionLog, false );
}
}
}
catch ( Exception )
{
// If logging the exception fails, write the exceptions to a file
try
{
string directory = AppDomain.CurrentDomain.BaseDirectory;
directory = Path.Combine( directory, "App_Data", "Logs" );
if ( !Directory.Exists( directory ) )
{
Directory.CreateDirectory( directory );
}
string filePath = Path.Combine( directory, "RockExceptions.csv" );
string when = RockDateTime.Now.ToString();
while ( ex != null )
{
File.AppendAllText( filePath, string.Format( "{0},{1},\"{2}\"\r\n", when, ex.GetType(), ex.Message ) );
ex = ex.InnerException;
}
}
catch
{
// failed to write to database and also failed to write to log file, so there is nowhere to log this error
}
}
}