5,446,542 members and growing! (18,966 online)
Email Password   helpLost your password?
Languages » C# » General     Beginner

Navigating Exception Backtraces in Visual Studio

By henon the hacker

A code snippet to print exceptions and inner exceptions in Visual Studio's error parser format.
C# 2.0, C#, Windows, .NET, .NET 2.0VS2005, Visual Studio, Dev

Posted: 21 Nov 2007
Updated: 21 Nov 2007
Views: 3,933
Bookmarked: 6 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
6 votes for this Article.
Popularity: 2.88 Rating: 3.71 out of 5
1 vote, 16.7%
1
1 vote, 16.7%
2
0 votes, 0.0%
3
0 votes, 0.0%
4
4 votes, 66.7%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

Ever been angry about Visual Studio's inability to provide easy exception backtrace navigation? Here is the solution:

I wrote a nice little debug helper function called PrintException which has proven very useful to me and my team for our everyday work. It prints the relevant informations about an exception and its inner exceptions to the output recursively. The clue is, that it does this in a format that is understood by the error parser of Microsoft Visual Studio. So if you get an exception you can easily navigate to the excact locations in your source files by double-clicking on the lines in the printed stacktrace. It also prints all inner exceptions recursively with increasing indent for better readability.

Using the code

Basically all you need to do is to wrap your main routine with a try-catch statement and call Debug.PrintException(e); on the caught exception e. Once the exception has been printed to standard out you may also stop the debugger and you still can navigate to the source of error by double-clicking on a backtrace line. Here is an example:
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); }
    Console.ReadLine();
  }
} 

The formatted exceptions in the output window look like this:

********************************************************************************
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()
******************************************************************************** 

As I have experienced, the most inner exception is the most important one, so I do a depth first recursion on the inner exceptions. Your milage may vary ...

Note: Error parser formatting works, of course, only when the exception is raised in an assembly that has been compiled in debug mode. Also the redirection of standard out to Visual Studio's output window (the only place where you can navigate using the built-in error parser) is only activated by default for a Windows Forms application not for a Console application.

The Code

Since the code snippet that does the exception formatting is so tiny I put it up here directly:

using System;

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

That's it. Works very well for me. Let me know if you came across a special case where the formatting did not work.

If you are interested in my other articles see my Blog on C# and Ruby.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

henon the hacker


Henon (aka Meinrad Recheis) is an Austrian computer science student who loves the programming languages C# and Ruby.

Occupation: Web Developer
Location: Austria Austria

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 7 of 7 (Total in Forum: 7) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralGood Ideamembermkavaleuski3:22 10 Dec '07  
GeneralCouldn't one do it like this ?memberxavier_k2y18:59 26 Nov '07  
GeneralRe: Couldn't one do it like this ?memberhenon the hacker0:46 27 Nov '07  
GeneralRe: Couldn't one do it like this ?memberxavier_k2y1:26 27 Nov '07  
GeneralCool Ideamembermerlin9814:53 23 Nov '07  
GeneralNicememberCorinna John4:28 22 Nov '07  
GeneralRe: Nicememberhenon the hacker6:28 22 Nov '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 21 Nov 2007
Editor:
Copyright 2007 by henon the hacker
Everything else Copyright © CodeProject, 1999-2008
Web09 | Advertise on the Code Project