Getting Exception Information






Getting Exception Information

Problem

There are several different methods of getting exception information. You need to choose the best one to use.

Solution

The .NET platform supports several mechanisms for displaying exception information, depending on the specific type of information that you want to show. The easiest method is to use the ToString method of the thrown exception object, usually in the catch block of an exception handler:

	catch(Exception e)
	{
	    Console.WriteLine(e.ToString( ));
	}

Another mechanism is to manually display the individual properties of the exception and iterate through each inner exception, if any exist. The default Exception. ToString method will iterate over the inner exceptions as well, so if you want to make sure you get all of that information, you need to roll over them when examining the properties directly. For example, the custom method shown in Figure is called from a catch block. It takes a single exception object as a parameter and proceeds to display its information, including information on all inner exceptions and the exception data block.

Displaying exception information, including information on all inner exceptions and the exception data block

public static int exceptionLevel = 0;
public static void DisplayException(Exception e)
{
    // Increment exception level.
    exceptionLevel++;
    // Make spacer for level.
    string indent = new string('\t',exceptionLevel-1);
    // Write out exception level data.
    Console.WriteLine(indent + "*** Exception Level {0} " +
                      "***************************************", exceptionLevel);
    Console.WriteLine(indent + "ExceptionType: " + e.GetType().Name.ToString());
    Console.WriteLine(indent + "HelpLine: " + e.HelpLink);
    Console.WriteLine(indent + "Message: " + e.Message);
    Console.WriteLine(indent + "Source: " + e.Source);
    Console.WriteLine(indent + "StackTrace: " + e.StackTrace);
    Console.WriteLine(indent + "TargetSite: " + e.TargetSite);
    Console.WriteLine(indent + "Data:");
    foreach (DictionaryEntry de in e.Data)
    {
        Console.WriteLine(indent + "\t{0} : {1}",de.Key,de.Value);
    }
    
    // Get the inner exception for this exception.
    Exception ie = e.InnerException;
    
    // Print out the inner exceptions recursively.
    while(ie != null)
    {
        DisplayException(ie);
        // Check to see if we are doing the inner exceptions.
        if(exceptionLevel>1)
            ie = ie.InnerException;
        else // back to main level
            ie = null;
    }
    // Decrement exception level.
    exceptionLevel--;
}

Discussion

A typical exception object of type Exception displays the following information if its ToString method is called:

	System.Exception: Exception of type System.Exception was thrown.
	    at Chapter_Code.Chapter7.TestSpecializedException( ) in c:\book cs cookbook\code\
	        test.cs:line 286

Three pieces of information are shown here:

  • The exception type (Exception in this case) followed by a colon

  • The string contained in the exception's Message property

  • The string contained in the exception's StackTrace property

The great thing about the ToString method is that information about any exception contained in the InnerException property is automatically displayed as well. The following text shows the output of an exception that wraps an inner exception:

	System.Exception: Exception of type System.Exception was thrown.
	---> System.Exception: The Inner Exception
	   at Chapter_Code.Chapter7.TestSpecializedException( )
	     in c:\book cs cookbook\code\
	     test.cs:line 306
	   --- End of inner exception stack trace ---
	   at Chapter_Code.Chapter7.TestSpecializedException( )
	     in c:\book cs cookbook\code\
	     test.cs:line 310

The same three pieces of information are displayed for each exception. The output is broken down into the following format:

	Outer exception type: Outer exception Message property
	---> Inner Exception type: Inner exception Message property
	Inner Exception StackTrace property
	    --- End of inner exception stack trace ---
	Outer exception StackTrace property

If the inner exception contains an exception object in its InnerException property, that exception is displayed as well. In fact, information for all inner exceptions is displayed in this format.

Calling the ToString method is a quick, useful way of getting the most pertinent information out of the exception and displaying it in a formatted string. However, not all of the exception's information is displayed. There might be a need to display the HelpLine or Source properties of the exception. In fact, if this is a user-defined exception, there could be custom fields that need to be displayed or captured in an error log. Also, you might not like the default formatting that the ToString method offers, or you may want to see the information in the Data collection of items. In these cases, consider writing your own method to display the exception's information based on the DisplayException method shown in the Solution.

To illustrate the custom method presented in the Solution section (the DisplayException method), consider the following code, which throws an exception wrapping two inner exceptions:

	Exception InnerInner = new Exception("The InnerInner Exception.");
	InnerInner.Data.Add("Key1 for InnerInner", "Value1 for InnerInner");

	ArgumentException Inner = new ArgumentException("The Inner Exception.", InnerInner);
	Inner.Data.Add("Key1 for Inner", "Value1 for Inner");
	NullReferenceException se = new NullReferenceException("A Test Message.", Inner);
	se.HelpLink = "MyComponent.hlp";
	se.Source = "MyComponent";
	se.Data.Add("Key1 for Outer", "Value1 for Outer");
	se.Data.Add("Key2 for Outer", "Value2 for Outer");
	se.Data.Add("Key3 for Outer", "Value3 for Outer");

	try
	{
	    throw (se);
	}
	catch(Exception e)
	{
	    DisplayException(e);
	}

If this code were executed, DisplayException would display the following:

	*** Exception Level 1 ***************************************
	ExceptionType: NullReferenceException
	HelpLine: MyComponent.hlp
	Message: A Test Message.
	Source: MyComponent
	StackTrace:     at CSharpRecipes.ExceptionHandling.TestDisplayException() in C:\PRJ32\
	Book_2_0\C#Cookbook2\Code\CSharpRecipes\07_ExceptionHandling.cs:line 371
	TargetSite: Void TestDisplayException()
	Data:
	    Key1 for Outer : Value1 for Outer
	    Key2 for Outer : Value2 for Outer
	    Key3 for Outer : Value3 for Outer
	    *** Exception Level 2 ***************************************
	    ExceptionType: ArgumentException
	    HelpLine:
	    Message: The Inner Exception.
	    Source:
	    StackTrace:
	    TargetSite:
	    Data:
	        Key1 for Inner : Value1 for Inner
	        *** Exception Level 3 ***************************************
	        ExceptionType: Exception
	        HelpLine:
	        Message: The InnerInner Exception.
	        Source:
	        StackTrace:
	        TargetSite:
	        Data:
	            Key1 for InnerInner : Value1 for InnerInner

The outermost exception is displayed first, followed by all of its properties. Next, each inner exception is displayed in a similar manner.

The while loop of the DisplayException method is used to iterate through each inner exception until the innermost exception is reached. The indent variable is used to create the staggered display of inner exception information based on the level of the exception.

See Also

See the "Error Raising and Handling Guidelines" and "Exception Class" topics in the MSDN documentation.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows