using System.Text.RegularExpressions; namespace ColorControl.Shared.Common { /// /// Extension methods for Exception class. /// public static class ExceptionExtensions { /// /// Provides full stack trace for the exception that occurred. /// /// Exception object. /// Environment stack trace, for pulling additional stack frames. public static string ToLogString(this Exception exception, string environmentStackTrace = "") { List environmentStackTraceLines = GetUserStackTraceLines(environmentStackTrace); if (environmentStackTraceLines.Any()) { environmentStackTraceLines.RemoveAt(0); } List stackTraceLines = GetStackTraceLines(exception.StackTrace); stackTraceLines.AddRange(environmentStackTraceLines); string fullStackTrace = string.Join(Environment.NewLine, stackTraceLines); string logMessage = exception.Message + Environment.NewLine; if (exception.InnerException != null) { logMessage += $"Inner exception: {exception.InnerException.Message}{Environment.NewLine}"; } logMessage += fullStackTrace; return logMessage; } /// /// Gets a list of stack frame lines, as strings. /// /// Stack trace string. private static List GetStackTraceLines(string stackTrace) { return stackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(); } /// /// Gets a list of stack frame lines, as strings, only including those for which line number is known. /// /// Full stack trace, including external code. private static List GetUserStackTraceLines(string fullStackTrace) { List outputList = new List(); Regex regex = new Regex(@"([^\)]*\)) in (.*):([A-z]*) (\d)*$"); List stackTraceLines = GetStackTraceLines(fullStackTrace); foreach (string stackTraceLine in stackTraceLines) { if (!regex.IsMatch(stackTraceLine)) { continue; } outputList.Add(stackTraceLine); } return outputList; } } }