Home > Articles

Advanced CLR Topics

This chapter is from the book

Exception Handling in .NET

When writing code, one thing you can be sure of is that errors may occur. Typically you code will call Application Programming Interfaces (APIs) or other functions, and those functions may run into trouble. One approach for dealing with these errors is to monitor return values from functions to make sure that the intended result happened. The idea is to look for a successful return code and continue execution or detect that a failure has occurred and then handle the error condition correctly and gracefully terminate execution.

This works fine until you call a function or library that does not properly handle all possible error conditions. When this happens, the error can sometimes be passed back to your code and unexpected problems can occur. Exceptions provide a standardized way to generate and detect these errors before they can become a more serious problem in your application.

Exceptions allow you to build applications that make a call to another function and then catch errors if they occur and handle them in the calling application. However, exception handling differs from one programming language to another, if it is even supported at all! The Common Language Runtime solves this problem for all applications that use it. This section focuses on exception handling construction for Managed C++ application using the Common Language Runtime. The concepts are the same as traditional C++ exception handling, but the details vary a little.

Managed Exception Handling

Using exceptions in applications when you are using the Common Language Runtime provides the following benefits:

  • Exceptions can be handled regardless of the language that generated the exception or the one that is handling it.

  • Exceptions can be thrown (generated) from one process to another or even from a remote machine.

  • Exceptions can be thrown and caught in either managed or unmanaged code allowing you to work with exceptions outside of the environment that you are currently working in.

  • Exceptions in the Common Language Runtime do not require any special syntax but allows each language to define its own.

  • Exception handling, using the Common Language Runtime, is faster than using the Windows-based C++ error handling.

The Exception Class

At the center of exceptions in the Common Language Runtime is the Exception class. This base class is the class from which all other exception classes are derived. A portion of the hierarchy is shown in Figure 25.3. Two of the most common exception classes are SystemException and ApplicationException. Both of these classes inherit from Exception class but do not add any additional functionality. Why the two separate classes? It makes it easier to determine the origin and severity of the exception.

Figure 25.3 Examples of classes derived from the Exception class.

SystemException is used for exceptions that are generated by the CLR. The severity of the exception can be mild (such as a NULL reference exception) or more severe (such as a stack overflow exception.) SystemException is also the class from which ExternalException is derived. This allows the CLR to create managed exceptions that contain information about unmanaged exceptions. It is normally recommended that you do not catch exceptions of type SystemException. Let the runtime catch them, since the application is unlikely to be able to continue after the exception has occurred.

ApplicationException is the base class for exceptions that are thrown as part of an application. You can derive your own exceptions from the ApplicationException class. This is the exception type that you will most often catch in your application.

The Exception class contains several properties that can be examined when the exception has been caught. Table 25.3 lists the public properties and their description. The SystemException and ApplicationException classes inherit these properties.

Table 25.3 Properties of the Exception Class

Property Name

Description

HelpLink

Contains a URL to more information about the exception. Set by the throwing function and may be blank

InnerException

Contains information about previous exceptions, if applicable. This can create a "stack" of exceptions that can show a chain of events

Message

Text that describes the details of the exception. Set by the throwing function.

Source

Specifies the object that threw the exception.

StackTrace

A string that show the function call stack at the time of the exception.

TargetSite

Name of the method that is throwing the exception.


Throwing Exceptions in Managed Code

When an error occurs in your application, you should throw an exception to signal to the caller that an error has occurred. The way you do this in managed code is very simple, as demonstrated in Listing 25.4.

Listing 25.4 Throwing an Exception in Managed Code

#using<mscorlib.dll>
using namespace System;

int main()
{
  Console::WriteLine(S"This is an example of throwing an exception");
  throw new Exception(S"A sample exception");
  return 0;
}

This simple sample only throws the exception, using the throw statement. The string that is passed to the new Exception object is passed to the Message property of the object and provides information to the handler of the exception.

NOTE

If you create a solution and use the code from Listing 25.4, then execute it under the debugger, you will see a dialog box that says that an unhandled exception has occurred. This dialog also provides information about the exception, if available, and gives you the option of continuing with execution or breaking into the code where the exception is being handled. If you execute the code normally, the Just in Time debugger (JIT) dialog will appear and give you the option of debugging the failure.

Throwing an exception is easy. Handling the exception is also easy.

Try/Catch Block Construction in Managed Code

The Common Language Runtime exceptions use the same mechanism as the C++ language for exception handling, which is the Try/Catch statements. The use is very similar to the way as C++ exceptions. However, there are some minor differences.

Normally, code that might throw an exception is in a try/catch block. Perhaps the throw statement is in a function, and the call to the function is in a try/catch block. This enables you to catch any exceptions thrown by the function. To extend the sample above you could add a try and catch block as shown in Listing 25.5.

Listing 25.5 A General Try/Catch Block for Exception Handling

#using<mscorlib.dll>
using namespace System;

int main()
{
 try
 {
  Console::WriteLine(S" This is an example of throwing an exception");
  throw new Exception(S"A sample exception");
 }
 catch(Exception* e)
 {
  Console::WriteLine(S"An exception has been caught: ");
  Console::WriteLine(e->ToString());
 }
 return 0;
}

The code in Listing 25.5 executes as the code of Listing 25.4 did, but now it traps the exception in the catch clause to examine the failure. First it writes to the screen that an exception has been caught and then it prints the important information in the exception object using the ToString method that is a member function of the Exception class.

In the example in Listing 25.5, the catch clause will catch any exception of the Exception object type. Normally, you construct a catch clause for a specific exception to handle the failure in our code and exit the error condition gracefully. For example, you passed a function a NULL parameter and the function did not support this then a System.ArgumentNullException would be generated.

try
{
 DoesNotAcceptNULL(NULL);
}
catch(ArgumentNullException* e)
{
 Console::WriteLine(S"A ArgumentNullException exception has been caught: ");
 Console::WriteLine(S"You should not pass NULL to this function");
}

The difference here is in the catch clause. This one catches only arguments of type ArgumentNullException[md]other exceptions will not be caught. You can catch several types of exceptions by coding several catch blocks, as in Listing 25.6.

Listing 25.6 Multiple Catch Blocks

try
{
 DoesNotAcceptNULL(char* pChar);
}
catch(ArgumentNullException* e)
{
 Console::WriteLine(S"A ArgumentNullException exception has been caught: ");
 Console::WriteLine(S"You should not pass NULL to this function");
}
catch(Exception* e)
{
 Console::WriteLine(S"An error has occurred, terminating application.");
}

You can write catch blocks for each exception type you expect. If you catch exceptions in this manner, you will be able to tailor the response to an exception on a case by case basis. You can also have a general exception handler to handle the error cases that you do not need to do any special processing before exiting your code.

CAUTION

The order of the catch blocks is important. Catch clauses are checked in the order they appear in your code and so it is important to put catch blocks for specific exceptions before those for general. Failing to do this can cause unexpected results.

Using the __finally Clause

When an exception occurs, the control of the application is passed to the first exception handler that is found when the stack is unwound as it is with traditional C++ exceptions. After the handler has been executed, the function where the exception occurred is exited. Often you may have housekeeping code that should be executed, but that won't be executed after the exception handler has been invoked. This can result in a duplication of code within the catch block and at the end of the try block. The __finally mechanism ensures that your cleanup code is executed after the exception handler is done with its work.

The __finally block defines the code that we want to execute after the exception handler is finished. The code in the __finally block is always executed, whether an exception was thrown or not, making it a perfect place for housekeeping work to be done for the function. Listing 25.6 shows an example.

Listing 25.6 Using the __finally Block

#using<mscorlib.dll>
using namespace System;

int main()
{
 int* buffer;
 try
 {
  int* buffer = new int[256];
 }
 
 catch(OutOfMemoryException* e)
 {
  // Handle the Out of Memory error condition if allocation failed
  Console::WriteLine(S"Memory allocation failed!");
 }

 __finally
 {
  // Do my normal housecleaning work here
  delete buffer;
 }
}

CAUTION

Remember that any code that is placed into the __finally clause will be executed whether an exception was handled or not. Do not include error-handling code in the __finally block.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020