예제 #1
0
        /// <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);
                }

                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
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Populates the <see cref="Rock.Model.ExceptionLog" /> entity with the exception data.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception" /> to log.</param>
        /// <param name="context">The <see cref="System.Web.HttpContext" />.</param>
        /// <param name="pageId">An <see cref="System.Int32" /> containing the Id of the <see cref="Rock.Model.Page" /> where the exception occurred.
        /// This value is nullable.</param>
        /// <param name="siteId">An <see cref="System.Int32" /> containing the Id the <see cref="Rock.Model.Site" /> where the exception occurred.
        /// This value is nullable.</param>
        /// <param name="personAlias">The person alias.</param>
        /// <returns></returns>
        private static ExceptionLog PopulateExceptionLog(Exception ex, HttpContext context, int?pageId, int?siteId, PersonAlias personAlias)
        {
            int?personAliasId = null;

            if (personAlias != null)
            {
                personAliasId = personAlias.Id;
            }

            string exceptionMessage = ex.Message;

            if (ex is System.Data.SqlClient.SqlException)
            {
                var sqlEx        = ex as System.Data.SqlClient.SqlException;
                var sqlErrorList = sqlEx.Errors.OfType <System.Data.SqlClient.SqlError>().ToList().Select(a => string.Format("{0}: Line {1}", a.Procedure, a.LineNumber));
                if (sqlErrorList.Any())
                {
                    exceptionMessage += string.Format("[{0}]", sqlErrorList.ToList().AsDelimited(", "));
                }
            }

            var exceptionLog = new ExceptionLog
            {
                SiteId            = siteId,
                PageId            = pageId,
                HasInnerException = ex.InnerException != null,
                ExceptionType     = ex.GetType().ToString(),
                Description       = exceptionMessage,
                Source            = ex.Source,
                StackTrace        = ex.StackTrace,
                Guid = Guid.NewGuid(),
                CreatedByPersonAliasId            = personAliasId,
                ModifiedByPersonAliasId           = personAliasId,
                CreatedDateTime                   = RockDateTime.Now,
                ModifiedDateTime                  = RockDateTime.Now,
                ModifiedAuditValuesAlreadyUpdated = true
            };

            if (exceptionLog.StackTrace == null)
            {
                try
                {
                    // if the Exception didn't include a StackTrace, manually grab it
                    var stackTrace = new System.Diagnostics.StackTrace(2);
                    exceptionLog.StackTrace = stackTrace.ToString();
                }
                catch
                {
                    // ignore
                }
            }

            try
            {
                ex.Data.Add("ExceptionLogGuid", exceptionLog.Guid);
            }
            catch
            {
                // ignore
            }

            try
            {
                // If current HttpContext is null, return early.
                if (context == null)
                {
                    return(exceptionLog);
                }

                // If current HttpContext is available, populate its information as well.
                var request = context.Request;

                StringBuilder cookies    = new StringBuilder();
                var           cookieList = request.Cookies;

                if (cookieList.Count > 0)
                {
                    cookies.Append("<table class=\"cookies exception-table\">");

                    foreach (string cookie in cookieList)
                    {
                        var httpCookie = cookieList[cookie];
                        if (httpCookie != null)
                        {
                            cookies.Append("<tr><td><b>" + cookie + "</b></td><td>" + httpCookie.Value.EncodeHtml() + "</td></tr>");
                        }
                    }

                    cookies.Append("</table>");
                }

                StringBuilder formItems = new StringBuilder();
                var           formList  = request.Form;

                if (formList.Count > 0)
                {
                    formItems.Append("<table class=\"form-items exception-table\">");

                    foreach (string formItem in formList)
                    {
                        formItems.Append("<tr><td><b>" + formItem + "</b></td><td>" + formList[formItem].EncodeHtml() + "</td></tr>");
                    }

                    formItems.Append("</table>");
                }

                StringBuilder serverVars    = new StringBuilder();
                var           serverVarList = request.ServerVariables;

                if (serverVarList.Count > 0)
                {
                    serverVars.Append("<table class=\"server-variables exception-table\">");

                    foreach (string serverVar in serverVarList)
                    {
                        serverVars.Append("<tr><td><b>" + serverVar + "</b></td><td>" + serverVarList[serverVar].EncodeHtml() + "</td></tr>");
                    }

                    serverVars.Append("</table>");
                }

                exceptionLog.Cookies         = cookies.ToString();
                exceptionLog.StatusCode      = context.Response.StatusCode.ToString();
                exceptionLog.PageUrl         = request.Url.ToString();
                exceptionLog.ServerVariables = serverVars.ToString();
                exceptionLog.QueryString     = request.Url.Query;
                exceptionLog.Form            = formItems.ToString();
            }
            catch {
                // Intentionally do nothing
            }

            return(exceptionLog);
        }
예제 #3
0
 /// <summary>
 /// To the dto.
 /// </summary>
 /// <param name="value">The value.</param>
 /// <returns></returns>
 public static ExceptionLogDto ToDto(this ExceptionLog value)
 {
     return(new ExceptionLogDto(value));
 }
예제 #4
0
 /// <summary>
 /// Instantiates a new DTO object from the entity
 /// </summary>
 /// <param name="exceptionLog"></param>
 public ExceptionLogDto(ExceptionLog exceptionLog)
 {
     CopyFromModel(exceptionLog);
 }
예제 #5
0
        /// <summary>
        /// Populates the <see cref="Rock.Model.ExceptionLog" /> entity with the exception data.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception" /> to log.</param>
        /// <param name="context">The <see cref="System.Web.HttpContext" />.</param>
        /// <param name="pageId">An <see cref="System.Int32" /> containing the Id of the <see cref="Rock.Model.Page" /> where the exception occurred.
        /// This value is nullable.</param>
        /// <param name="siteId">An <see cref="System.Int32" /> containing the Id the <see cref="Rock.Model.Site" /> where the exception occurred.
        /// This value is nullable.</param>
        /// <param name="personAlias">The person alias.</param>
        /// <returns></returns>
        private static ExceptionLog PopulateExceptionLog(Exception ex, HttpContext context, int?pageId, int?siteId, PersonAlias personAlias)
        {
            int?personAliasId = null;

            if (personAlias != null)
            {
                personAliasId = personAlias.Id;
            }

            string exceptionMessage = ex.Message;

            if (ex is System.Data.SqlClient.SqlException)
            {
                var sqlEx        = ex as System.Data.SqlClient.SqlException;
                var sqlErrorList = sqlEx.Errors.OfType <System.Data.SqlClient.SqlError>().ToList().Select(a => string.Format("{0}: Line {1}", a.Procedure, a.LineNumber));
                if (sqlErrorList.Any())
                {
                    exceptionMessage += string.Format("[{0}]", sqlErrorList.ToList().AsDelimited(", "));
                }
            }

            var exceptionLog = new ExceptionLog
            {
                SiteId            = siteId,
                PageId            = pageId,
                HasInnerException = ex.InnerException != null,
                ExceptionType     = ex.GetType().ToString(),
                Description       = exceptionMessage,
                Source            = ex.Source,
                StackTrace        = ex.StackTrace,
                Guid = Guid.NewGuid(),
                CreatedByPersonAliasId            = personAliasId,
                ModifiedByPersonAliasId           = personAliasId,
                CreatedDateTime                   = RockDateTime.Now,
                ModifiedDateTime                  = RockDateTime.Now,
                ModifiedAuditValuesAlreadyUpdated = true
            };

            if (exceptionLog.StackTrace == null)
            {
                try
                {
                    // if the Exception didn't include a StackTrace, manually grab it
                    var stackTrace = new System.Diagnostics.StackTrace(2);
                    exceptionLog.StackTrace = stackTrace.ToString();
                }
                catch
                {
                }
            }

            try
            {
                ex.Data.Add("ExceptionLogGuid", exceptionLog.Guid);
            }
            catch
            {
            }

            try
            {
                // If current HttpContext is null, return early.
                if (context == null)
                {
                    return(exceptionLog);
                }

                // If current HttpContext is available, populate its information as well.
                var request = context.Request;

                StringBuilder cookies    = new StringBuilder();
                var           cookieList = request.Cookies;

                if (cookieList.Count > 0)
                {
                    cookies.Append("<table class=\"cookies exception-table\">");

                    foreach (string cookie in cookieList)
                    {
                        var httpCookie = cookieList[cookie];
                        if (httpCookie != null)
                        {
                            cookies.Append("<tr><td><b>" + cookie + "</b></td><td>" + httpCookie.Value.EncodeHtml() + "</td></tr>");
                        }
                    }

                    cookies.Append("</table>");
                }

                StringBuilder serverVars = new StringBuilder();

                // 'serverVarList[serverVar]' throws an exception if the value is empty, even if the key exists,
                // so make a copy of the request server variables to help avoid that error
                var serverVarList       = new NameValueCollection(request.ServerVariables);
                var serverVarListString = serverVarList.ToString();

                var serverVarKeys = request.ServerVariables.AllKeys;

                if (serverVarList.Count > 0)
                {
                    serverVars.Append("<table class=\"server-variables exception-table\">");

                    foreach (string serverVar in serverVarList)
                    {
                        string val = string.Empty;
                        try
                        {
                            val = serverVarList[serverVar].ToStringSafe().EncodeHtml();
                        }
                        catch
                        {
                            // ignore
                        }

                        serverVars.Append($"<tr><td><b>{serverVar}</b></td><td>{val}</td></tr>");
                    }

                    serverVars.Append("</table>");
                }

                exceptionLog.Cookies         = cookies.ToString();
                exceptionLog.StatusCode      = context.Response.StatusCode.ToString();
                exceptionLog.PageUrl         = request.UrlProxySafe().ToString();
                exceptionLog.ServerVariables = serverVars.ToString();
                exceptionLog.QueryString     = request.UrlProxySafe().Query;

                /*
                 *   SK - 11/24/2021
                 *   We are commenting out below line as we have decided not to store form data from now on as it may contain sensative data.
                 *   exceptionLog.Form = formItems.ToString();
                 */
            }
            catch
            {
            }

            return(exceptionLog);
        }
예제 #6
0
        /// <summary>
        /// Populates the <see cref="Rock.Model.ExceptionLog" /> entity with the exception data.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception" /> to log.</param>
        /// <param name="request">The <see cref="T:System.Net.HttpRequestMessage" />.</param>
        /// <param name="personAlias">The person alias.</param>
        /// <returns></returns>
        private static ExceptionLog PopulateExceptionLog(Exception ex, HttpRequestMessage request, PersonAlias personAlias)
        {
            string exceptionMessage = ex.Message;

            if (ex is System.Data.SqlClient.SqlException)
            {
                var sqlEx        = ex as System.Data.SqlClient.SqlException;
                var sqlErrorList = sqlEx.Errors.OfType <System.Data.SqlClient.SqlError>().ToList().Select(a => string.Format("{0}: Line {1}", a.Procedure, a.LineNumber));
                if (sqlErrorList.Any())
                {
                    exceptionMessage += string.Format("[{0}]", sqlErrorList.ToList().AsDelimited(", "));
                }
            }

            var exceptionLog = new ExceptionLog
            {
                HasInnerException = ex.InnerException != null,
                ExceptionType     = ex.GetType().ToString(),
                Description       = exceptionMessage,
                Source            = ex.Source,
                StackTrace        = ex.StackTrace,
                Guid = Guid.NewGuid(),
                CreatedByPersonAliasId            = personAlias?.Id,
                ModifiedByPersonAliasId           = personAlias?.Id,
                CreatedDateTime                   = RockDateTime.Now,
                ModifiedDateTime                  = RockDateTime.Now,
                ModifiedAuditValuesAlreadyUpdated = true
            };

            if (exceptionLog.StackTrace == null)
            {
                try
                {
                    // if the Exception didn't include a StackTrace, manually grab it
                    var stackTrace = new System.Diagnostics.StackTrace(2);
                    exceptionLog.StackTrace = stackTrace.ToString();
                }
                catch
                {
                }
            }

            try
            {
                ex.Data.Add("ExceptionLogGuid", exceptionLog.Guid);
            }
            catch
            {
            }

            try
            {
                // If current HttpRequestMessage is null, return early.
                if (request == null)
                {
                    return(exceptionLog);
                }

                StringBuilder cookies    = new StringBuilder();
                var           cookieList = request.Headers.GetCookies();

                if (cookieList.Count > 0)
                {
                    cookies.Append("<table class=\"cookies exception-table\">");

                    foreach (var cookieHeaderValue in cookieList)
                    {
                        foreach (var cookie in cookieHeaderValue.Cookies)
                        {
                            cookies.Append("<tr><td><b>" + cookie.Name + "</b></td><td>" + cookie.Value.EncodeHtml() + "</td></tr>");
                        }
                    }

                    cookies.Append("</table>");
                }

                //
                // Check query string parameters for sensitive data.
                //
                string queryString     = null;
                var    queryCollection = request.RequestUri.ParseQueryString();
                if (queryCollection.Count > 0)
                {
                    var nvc = new NameValueCollection();
                    foreach (string qKey in queryCollection.Keys)
                    {
                        if (IsKeySensitive(qKey.ToLower()))
                        {
                            nvc.Add(qKey, "obfuscated");
                        }
                        else
                        {
                            nvc.Add(qKey, queryCollection[qKey]);
                        }
                    }

                    queryString = "?" + string.Join("&", nvc.AllKeys.Select(a => a.UrlEncode() + "=" + nvc[a].UrlEncode()));
                }

                exceptionLog.Cookies     = cookies.ToString();
                exceptionLog.PageUrl     = request.RequestUri.GetLeftPart(UriPartial.Path);
                exceptionLog.QueryString = queryString;
            }
            catch
            {
            }

            return(exceptionLog);
        }