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;
}
}
}