Exceptions and Errors

Exceptions and Errors

Well-behaved COM server objects don't usually throw exceptions back to their clients , but they can. So, to be cautious it's a good idea to put most of your COM- related code in a try block and follow it with a catch block for COM errors. COM errors are encapsulated in the Visual C++ compiler helper class _com_error.

Other than that, you need to know about HRESULT. This is a 32-bit data structure used to return status information about calls to methods in the COM APIs. You can't just check on a nonzero return value to see whether or not a call failed; it is a more complex data structure than that. Visual C++ provides some macros to check on HRESULT. I use FAILED and SUCCEEDED. Both return booleans. You'll see that the book's code also checks on some more specific return values associated with the MSXML DOM implementation.

If you want to do by-the-book COM programming, you will check for the HRESULT return from every method call to a COM interface. We could do this, but the code would be littered with status checks that in 99.9 percent of the cases would never execute the failure branch. I instead rely primarily on schema validation to enforce some expectations about the input XML documents we'll be processing and check for NULL pointers where applicable .

COM Classes and Data Types for C++

This is a brief list of the nonnative C++ COM data types and helper classes you are likely to have to deal with when using MSXML.

  • VARIANT, encapsulated as a COM helper class in C++ as _variant_t : This data type is the most awkward . It's a structure with several fields. The first one is a VARTYPE that specifies the type of VARIANT, that is, the data type of the data stored in the VARIANT. The last one is a union of several field types that contains the value of the VARIANT. There are only a few DOM methods that use a VARIANT, and for each I show how to set up the VARIANT.

  • BSTR Binary String data type, encapsulated as a COM helper class in C++ as _bstr_t : COM uses this in several places, but we mostly use it to represent character data in a VARIANT. A BSTR can be cast as TEXT, TCHAR, and LPTSTR to handle character sets other than the default. To keep things simple, we'll just use the BSTR whenever possible. Visual C++ usually is perfectly happy treating a _bstr_t as a char *.

VARIANT in the MSXML DOM Implementation

We most often have to deal with the VARIANT data type in the DOM get and set NodeValue methods. In the W3C DOM Recommendation these have different return and argument values depending on the Node type. For example, getNodeValue on a Text Node returns the text associated with the parent Element. When called on a Processing Instruction Node it returns the entire content excluding the target. When called on almost anything else it returns a NULL. From the perspective of someone developing a DOM API, using a VARIANT is a perfectly logical choice. However, it doesn't make life very easy for someone using the API. Java's JAXP is much easier to use in this regard, and so is the DOM implementation in System.XML in .NET.

If you find something in the book's code or in the MSXML sample code that isn't listed here, you can usually learn more about it by performing an index or search in the MSDN Library (available online at http://msdn.microsoft.com/library or from online help in Visual Studio).