18.8 Exception Class Methods and PropertiesSo far you've been using the exception as a sentinel — that is, the presence of the exception signals the errors — but you haven't touched or examined the Exception object itself. The System.Exception class provides a number of useful methods and properties. The Message property provides information about the exception, such as why it was thrown. The Message property is read-only; the code throwing the exception can pass in the message as an argument to the exception constructor, but the Message property cannot be modified by any method once set in the constructor. The HelpLink property provides a link to a help file associated with the exception. This property is read/write. In Example 18-6, the Exception.HelpLink property is set and retrieved to provide information to the user about the DivideByZeroException. It is generally a good idea to provide a help file link for any exceptions you create, so that the user can learn how to correct the exceptional circumstance. The read-only StackTrace property is set by the CLR. This property is used to provide a stack trace for the error statement. A stack trace is used to display the call stack: the series of method calls that lead to the method in which the exception was thrown. Example 18-6. Inside the Exception classusing System; namespace ExceptionHandling { class Tester { public void Run() { try { Console.WriteLine("Open file here"); double a = 12; double b = 0; Console.WriteLine ("{0} / {1} = {2}", a, b, DoDivide(a,b)); Console.WriteLine ( "This line may or may not print"); } // most derived exception type first catch (System.DivideByZeroException e) { Console.WriteLine( "\nDivideByZeroException! Msg: {0}", e.Message); Console.WriteLine( "\nHelpLink: {0}", e.HelpLink); Console.WriteLine( "\nHere's a stack trace: {0}\n", e.StackTrace); } catch { Console.WriteLine( "Unknown exception caught"); } finally { Console.WriteLine ( "Close file here."); } } // do the division if legal public double DoDivide(double a, double b) { if (b == 0) { DivideByZeroException e = new DivideByZeroException(); e.HelpLink = "http://www.libertyassociates.com"; throw e; } if (a == 0) throw new ArithmeticException(); return a/b; } static void Main() { Console.WriteLine("Enter Main..."); Tester t = new Tester(); t.Run(); Console.WriteLine("Exit Main..."); } } } Output: Enter Main... Open file here DivideByZeroException! Msg: Attempted to divide by zero. HelpLink: http://www.libertyassociates.com Here's a stack trace: at ExceptionHandling.Tester.DoDivide(Double a, Double b) in class1.cs:line 54 at ExceptionHandling.Tester.Run() in class1.cs:line 14 Close file here. Exit Main... In the output of Example 18-6, the stack trace lists the methods in the reverse order in which they were called; by reviewing this order, you can infer that the error occurred in DoDivide(), which was called by Run(). When methods are deeply nested, the stack trace can help you understand the order of method calls and thus track down the point at which the exception occurred. In this example, rather than simply throwing a DivideByZeroException, you create a new instance of the exception: DivideByZeroException e = new DivideByZeroException(); You do not pass in a custom message, and so the default message is printed: DivideByZeroException! Msg: Attempted to divide by zero.
If you want, you can modify this line of code to pass in a custom message: new DivideByZeroException( "You tried to divide by zero which is not meaningful"); In this case, the output message reflects the custom message: DivideByZeroException! Msg: You tried to divide by zero which is not meaningful Before throwing the exception, set the HelpLink property: e.HelpLink = "http://www.libertyassociates.com"; When this exception is caught, Console.WriteLine prints both the Message and the HelpLink: catch (System.DivideByZeroException e) { Console.WriteLine("\nDivideByZeroException! Msg: {0}", e.Message); Console.WriteLine("\nHelpLink: {0}", e.HelpLink); The Message and HelpLink properties allow you to provide useful information to the user. The exception handler also prints the StackTrace by getting the StackTrace property of the Exception object: Console.WriteLine("\nHere's a stack trace: {0}\n", e.StackTrace); The output of this call reflects a full StackTrace leading to the moment the exception was thrown. In this case, only two methods were executed before the exception, DoDivide() and Run(): Here's a stack trace: at ExceptionHandling.Tester.DoDivide(Double a, Double b) in class1.cs:line 54 at ExceptionHandling.Tester.Run() in class1.cs:line 14 Note that I've shortened the pathnames, so your printout might look a little different. |