My understanding of it (based on some related MSDN pages) is that by implementing ISupportErrorInfo
, you are indicating that one or more interfaces on your class returns error information by calling SetErrorInfo
, as opposed to just returning a failure HRESULT
.
To that end, your implementation of ISuportErrorInfo::InterfaceSupportsErrorInfo
should return S_OK
only for those interfaces on your class that actually use SetErrorInfo
to return error information to the caller, and only those interfaces.
For example, say you have a class that implements an interface you wrote called IFoo
that has a DoSomething
method. If someone else creates an instance of your class and calls IFoo::DoSomething
, they are supposed to do the following if DoSomething
returns a failure HRESULT
(paraphrasing from various MSDN pages, but I started from here: http://msdn.microsoft.com/en-us/library/ms221510.aspx):
Call QueryInterface
on the IFoo
pointer to get the ISupportErrorInfo
interface for the object that is implementing IFoo
If the called object doesn't implement ISupportErrorInfo
,
then the caller will have
to handle the error based on the
HRESULT
value, or pass it up the call stack.
If the called object does implement ISupportErrorInfo
, then the caller is supposed to QueryInterface
for a ISupportErrorInfo
pointer and call ISupportErrorInfo::InterfaceSupportsErrorInfo
, passing in a REFIID
for the interface that returned the error. In this case, the DoSomething
method of the IFoo
interface returned an error, so you would pass REFIID_IFoo
(assuming it's defined) to InterfaceSupportsErrorInfo
.
If InterfaceSupportsErrorInfo
returns S_OK
, then the caller
knows at this point that it can
retrieve more detailed information
about the error by calling
GetErrorInfo
. If InterfaceSupportsErrorInfo
returns S_FALSE
, the caller can assume the called interface doesn't supply detailed error information, and will have to rely on the returned HRESULT to figure out what happened.
The reason for this somewhat confusing/convoluted error-handling API seems to be for flexibility (as far I as I can tell anyway. This is COM after all ;). With this design, a class can support multiple interfaces, but not every interface is required to use SetErrorInfo
to return error information from its methods. You can have certain, select interfaces on your class return detailed error information via SetErrorInfo
, while other interfaces can continue to use normal HRESULT
s to indicate errors.
In summary, the ISupportErrorInfo
interface is a way to inform the calling code that at least one of the interfaces your class implements can return detailed error information, and the InterfaceSupportsErrorInfo
method tells the caller whether a given interface is one of those interfaces. If so, then the caller can retrieve the detailed error information by calling GetErrorInfo
.