Navigating in Exception Stack Traces in Visual C-Sharp

From eqqon

(Difference between revisions)
Jump to: navigation, search
(New page: Category:C-Sharp Today I wrote a nice little debug helper function called '''PrintException''' in C#. It prints all available information about an exception in a very structured way to...)
m
Line 1: Line 1:
-
[[Category:C-Sharp]]
+
[[Category:CSharp]]
Today I wrote a nice little debug helper function called '''PrintException''' in C#. It prints all available information about an exception in a very structured way to the output. The clue is, that it does this in a format that is understood by the error parser of Microsoft Visual Studio. So if one gets an exception one can easily navigate to the source locations by clicking on the lines in the printed stacktrace. It also prints inner exceptions recursively with increasing indent, which is extremely useful!
Today I wrote a nice little debug helper function called '''PrintException''' in C#. It prints all available information about an exception in a very structured way to the output. The clue is, that it does this in a format that is understood by the error parser of Microsoft Visual Studio. So if one gets an exception one can easily navigate to the source locations by clicking on the lines in the printed stacktrace. It also prints inner exceptions recursively with increasing indent, which is extremely useful!

Revision as of 11:01, 9 November 2007

Today I wrote a nice little debug helper function called PrintException in C#. It prints all available information about an exception in a very structured way to the output. The clue is, that it does this in a format that is understood by the error parser of Microsoft Visual Studio. So if one gets an exception one can easily navigate to the source locations by clicking on the lines in the printed stacktrace. It also prints inner exceptions recursively with increasing indent, which is extremely useful!

Here is a simple example of usage of Debug.PrintException:

public static class PrintExceptionTest 
{
	static void test() 
	{
		try { test1(); }
		catch( Exception e) { throw new Exception("outer exception message", e); }
	}
	
	static void test1()
	{
		throw new InvalidOperationException("inner exception message");
	}
	
	public static void Main() 
	{
		try { test(); }
		catch(Exception e) { Debug.PrintException(e); }
	}
}

Here is the output generated by the above exanple. Links to source files are recognized by Visual Studio's error parser. Works also in some other IDEs and editors like Scite:

********************************************************************************
Exception: "outer exception message"
--------------------------------------------------------------------------------
InnerException:
   ********************************************************************************
   InvalidOperationException: "inner exception message"
   --------------------------------------------------------------------------------
     c:\C#\snippets\print_exception.cs(58,1):   PrintExceptionTest.test1()
     c:\C#\snippets\print_exception.cs(48,1):   PrintExceptionTest.test()
   ********************************************************************************
  c:\C#\snippets\print_exception.cs(52,1):   PrintExceptionTest.test()
  c:\C#\snippets\print_exception.cs(65,1):   PrintExceptionTest.Main()
********************************************************************************

And here is the class:

	public static class Debug
	{
		public static void PrintException(Exception exception)
		{
			PrintException(exception, "");
		}

		public static void PrintException(Exception exception, string indent)
		{
			string stars = new string('*', 80);
			Console.WriteLine(indent + stars);
			Console.WriteLine(indent + "{0}: \"{1}\"", exception.GetType().Name, exception.Message);
			Console.WriteLine(indent + new string('-', 80));
			if (exception.InnerException != null)
			{
				Console.WriteLine(indent + "InnerException:");
				PrintException(exception.InnerException, indent + "   ");
			}
			foreach (string line in exception.StackTrace.Split(new string[] { " at " }, StringSplitOptions.RemoveEmptyEntries))
			{
				if (string.IsNullOrEmpty(line.Trim())) continue;
				string[] parts;
				parts = line.Trim().Split(new string[] { " in " }, StringSplitOptions.RemoveEmptyEntries);
				string class_info = parts[0];
				if (parts.Length == 2)
				{
					parts = parts[1].Trim().Split(new string[] { "line" }, StringSplitOptions.RemoveEmptyEntries);
					string src_file = parts[0];
					int line_nr = int.Parse(parts[1]);
					Console.WriteLine(indent + "  {0}({1},1):   {2}", src_file.TrimEnd(':'), line_nr, class_info);
				}
				else
					Console.WriteLine(indent + "  " + class_info);
			}
			Console.WriteLine(indent + stars);
		}
	}