Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   The System.Exception Class

The CLR allows an instance of any type to be thrown for an exception—from an Int32 to a String and beyond. However, Microsoft decided against forcing all programming languages to throw and catch exceptions of any type, so they defined the System.Exception type and decreed that all CLS- compliant programming languages must be able to throw and catch exceptions whose type is derived from this type. Exception types that are derived from System.Exception are said to be CLS-compliant. C# and many other language compilers allow your code to throw only CLS-compliant exceptions.

The System.Exception type is a very simple type that contains the properties described in Table 20-1. Usually, you will not write any code to query or access these properties in any way. Instead, when your application terminates due to an unhandled exception, you will look at these properties in the debugger or in a report that gets generated and written out to the Windows Application event log or crash dump.

 

TABLE 20-1Public Properties of the System.Exception Type

 

Property Access Type Description
Message Read-only String Contains helpful text indicating why the exception was thrown. The message is typically written to a log when a thrown exception is unhandled. Because end users do not see this message, the message should be as techni- cal as possible so that developers viewing the log can use the information in the message to fix the code when producing a new version.
Data Read-only IDictionary A reference to a collection of key-value pairs. Usually, the code throwing the exception adds entries to this collec- tion prior to throwing it; code that catches the excep- tion can query the entries and use the information in its exception-recovery processing.
Source Read/write String Contains the name of the assembly that generated the exception.
StackTrace Read-only String Contains the names and signatures of methods called that led up to the exception being thrown. This property is invaluable for debugging.
TargetSite Read-only MethodBase Contains the method that threw the exception.
HelpLink Read-only String Contains a URL (such as file://C:\MyApp\Help.htm #MyExceptionHelp) to documentation that can help a user understand the exception. Keep in mind that sound programming and security practices prevent users from ever being able to see raw unhandled exceptions, so unless you are trying to convey information to other programmers, this property is seldom used.

Property Access Type Description
InnerException Read-only Exception Indicates the previous exception if the current exception were raised while handling an exception. This read-only property is usually null. The Exception type also offers a public GetBaseException method that tra- verses the linked list of inner exceptions and returns the originally thrown exception.
HResult Read/write Int32 A 32-bit value that is used when crossing managed and native code boundaries. For example, when COM APIs return failure HRESULT values, the CLR throws an Exception-derived object and maintains the HRESULT value in this property.

 



I’d like to say a few words about System.Exception’s read-only StackTrace property. A catch block can read this property to obtain the stack trace indicating what methods were called that led up to the exception. This information can be extremely valuable when you’re trying to detect the cause of an exception so that you can correct your code. When you access this property, you’re actu- ally calling into code in the CLR; the property doesn’t simply return a string. When you construct a new object of an Exception-derived type, the StackTrace property is initialized to null. If you were to read the property, you wouldn’t get back a stack trace; you would get back null.

When an exception is thrown, the CLR internally records where the throw instruction occurred. When a catch block accepts the exception, the CLR records where the exception was caught. If, inside a catch block, you now access the thrown exception object’s StackTrace property, the code that implements the property calls into the CLR, which builds a string identifying all of the methods between the place where the exception was thrown and the filter that caught the exception.

       
   
 
 

 

The following code throws the same exception object that it caught and causes the CLR to reset its starting point for the exception.

 

private void SomeMethod() { try { ... }

catch (Exception e) {

...

throw e; // CLR thinks this is where exception originated.

// FxCop reports this as an error

}

}


In contrast, if you re-throw an exception object by using the throw keyword by itself, the CLR doesn’t reset the stack’s starting point. The following code re-throws the same exception object that it caught, causing the CLR to not reset its starting point for the exception.

 

private void SomeMethod() { try { ... }

catch (Exception e) {

...

throw; // This has no effect on where the CLR thinks the exception

// originated. FxCop does NOT report this as an error

}

}

 

In fact, the only difference between these two code fragments is what the CLR thinks is the original location where the exception was thrown. Unfortunately, when you throw or re-throw an exception, Windows does reset the stack’s starting point. So if the exception becomes unhandled, the stack loca- tion that gets reported to Windows Error Reporting is the location of the last throw or re-throw, even though the CLR knows the stack location where the original exception was thrown. This is unfortunate because it makes debugging applications that have failed in the field much more difficult. Some de- velopers have found this so intolerable that they have chosen a different way to implement their code to ensure that the stack trace truly reflects the location where an exception was originally thrown.

 

private void SomeMethod() { Boolean trySucceeds = false; try {

...

trySucceeds = true;

}

finally {

if (!trySucceeds) { /* catch code goes in here */ }

}

}

 

The string returned from the StackTrace property doesn’t include any of the methods in the call stack that are above the point where the catch block accepted the exception object. If you want the complete stack trace from the start of the thread up to the exception handler, you can use the System.Diagnostics.StackTrace type. This type defines some properties and methods that allow a developer to programmatically manipulate a stack trace and the frames that make up the stack trace.

You can construct a StackTrace object by using several different constructors. Some constructors build the frames from the start of the thread to the point where the StackTrace object is con- structed. Other constructors initialize the frames of the StackTrace object by using an Exception- derived object passed as an argument.

If the CLR can find debug symbols (located in the .pdb files) for your assemblies, the string re- turned by System.Exception’s StackTrace property or System.Diagnostics.StackTrace’s ToString method will include source code file paths and line numbers. This information is incredibly useful for debugging.


Whenever you obtain a stack trace, you might find that some methods in the actual call stack don’t appear in the stack trace string. There are two reasons for this. First, the stack is really a record of where the thread should return to, not where the thread has come from. Second, the just-in-time (JIT) compiler can inline methods to avoid the overhead of calling and returning from a separate method.

Many compilers (including the C# compiler) offer a /debug command-line switch. When this switch is used, these compilers embed information into the resulting assembly to tell the JIT compiler not to inline any of the assembly’s methods, making stack traces more complete and meaningful to the developer debugging the code.

       
   
 
 

 

 


Date: 2016-03-03; view: 728


<== previous page | next page ==>
Nbsp;   Exception-Handling Mechanics | Nbsp;   FCL-Defined Exception Classes
doclecture.net - lectures - 2014-2025 year. Copyright infringement or personal data (0.116 sec.)