예제 #1
0
 /// <summary>
 /// Clones this ExceptionLog object to a new ExceptionLog object
 /// </summary>
 /// <param name="source">The source.</param>
 /// <param name="deepCopy">if set to <c>true</c> a deep copy is made. If false, only the basic entity properties are copied.</param>
 /// <returns></returns>
 public static ExceptionLog Clone(this ExceptionLog source, bool deepCopy)
 {
     if (deepCopy)
     {
         return(source.Clone() as ExceptionLog);
     }
     else
     {
         var target = new ExceptionLog();
         target.CopyPropertiesFrom(source);
         return(target);
     }
 }
        /// <summary>
        /// Recursively logs exception and any children.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> to log.</param>
        /// <param name="log">The parent <see cref="Rock.Model.ExceptionLog"/> of the exception being logged. This value is nullable.</param>
        /// <param name="isParent">A <see cref="System.Boolean"/> flag indicating if this Exception is a parent exception. This value is
        ///     <c>true</c> if the exception that is being logged is a parent exception, otherwise <c>false</c>.
        /// </param>
        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);
                }
            }
            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
                }
            }
        }