/// <summary> /// Returns a more complete text dump of this exception, than just its text. /// </summary> public static string ToFullMessage(this Exception error, string additionalMessage, bool includeStackTrace, bool includeSource, bool includeData) { if (error == null) { throw new NullReferenceException("This exception object is null"); } var r = new StringBuilder(); r.AppendLineIf(additionalMessage, additionalMessage.HasValue()); var err = error; while (err != null) { r.AppendLine(err.Message); if (includeData && err.Data != null) { r.AppendLine("\r\nException Data:\r\n{"); foreach (var i in err.Data) { r.AppendLine(ToLogText(i).WithPrefix(" ")); } r.AppendLine("}"); } if (err is ReflectionTypeLoadException) { foreach (var loaderEx in (err as ReflectionTypeLoadException).LoaderExceptions) { r.AppendLine("Type load exception: " + loaderEx.ToFullMessage()); } } try { r.AppendLineIf((err as HttpUnhandledException)?.GetHtmlErrorMessage().TrimBefore("Server Error")); } catch { // No logging is needed } err = err.InnerException; if (err != null) { r.AppendLine(); if (includeStackTrace) { r.AppendLine("###############################################"); } r.Append("Base issue: "); } } if (includeStackTrace && error.StackTrace.HasValue()) { var stackLines = error.StackTrace.Or("").Trim().ToLines(); stackLines = stackLines.Except(l => l.Trim().StartsWith("at System.Data.")).ToArray(); r.AppendLine(stackLines.ToString("\r\n\r\n").WithPrefix("\r\n--------------------------------------\r\nSTACK TRACE:\r\n\r\n")); } return(r.ToString()); }