The best solution I have found is writing an Exception column in Debug.Console , and then letting Visual Studio's built-in line of code parser provide navigation.
It was very useful for me to deal with unhandled exceptions in AppDomain and WPF Manager since Visual Studio always breaks too late.
Based on the article about Code Project , I changed it so that it displayed on the console as a single block of text, and not on the -by-line line - which was necessary, I also write entries to the console.
Using
public void ReportException(Exception exception) { if (Debugger.IsAttached) { DebugHelper.PrintExceptionToConsole(exception); Debugger.Break(); }
A source
public static class DebugHelper { // Original idea taken from the CodeProject article // http://www.codeproject.com/Articles/21400/Navigating-Exception-Backtraces-in-Visual-Studio private static readonly string StarSeparator = new String('*', 80); private static readonly string DashSeparator = new String('-', 80); private const string TabString = " "; /// <summary> /// Prints the exception using a format recognized by the Visual Studio console parser. /// Allows for quick navigation of exception call stack. /// </summary> /// <param name="exception">The exception.</param> public static void PrintExceptionToConsole(Exception exception) { using (var indentedTextWriter = new IndentedTextWriter(Console.Out, TabString)) { var indentLevel = 0; while (exception != null) { indentedTextWriter.Indent = indentLevel; indentedTextWriter.Write(FormatExceptionForDebugLineParser(exception)); exception = exception.InnerException; indentLevel++; } } } private static string FormatExceptionForDebugLineParser(Exception exception) { StringBuilder result = new StringBuilder(); result.AppendLine(StarSeparator); result.AppendLineFormat(" {0}: \"{1}\"", exception.GetType().Name, exception.Message); result.AppendLine(DashSeparator); // Split lines into method info and filename / line number string[] lines = exception.StackTrace.Split(new string[] { " at " }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .Where(x => !String.IsNullOrEmpty(x)) .ToArray(); foreach (var line in lines) { string[] parts = line.Split(new string[] { " in " }, StringSplitOptions.RemoveEmptyEntries); string methodInfo = parts[0]; if (parts.Length == 2) { string[] subparts = parts[1].Split(new string[] { ":line " }, StringSplitOptions.RemoveEmptyEntries); result.AppendLineFormat(" {0}({1},1): {2}", subparts[0], Int32.Parse(subparts[1]), methodInfo); } else result.AppendLineFormat(" {0}", methodInfo); } result.AppendLine(StarSeparator); return result.ToString(); } }
To use the above, as is, you will also need the extension method below and add the System.CodeDom.Compiler namespace to IndentedTextWriter .
Extension method
/// <summary> /// Appends the string returned by processing a composite format string followed by the default line terminator. /// </summary> /// <param name="sb">The StringBuilder.</param> /// <param name="format">The format.</param> /// <param name="args">The args.</param> public static void AppendLineFormat(this StringBuilder sb, string format, params object[] args) { sb.AppendFormat(format, args); sb.AppendLine(); }
Dennis
source share