Error Handling

Almost all COM functions return an HRESULT. If it’s other than S_OK, the question then becomes, how to handle it.

In the Win32, a system may return ’error’ (see docs). If you want additional info, call GetLastError to get a system error code, and then call FormatMessage

The COM equivalent is similar, but COM-based. (Things are a little different over IDispatch).

Server

The server implements ISupportErrorInfo to let clients know that it supports error info for a given interface. Then it uses ICreateErrorInfo to create a new IErrorInfo object. The it calls the Win32 SetErrorInfo.

Client side

The client calls ISupportErrorInfo::InterfaceSupportsErrorInfo to see if the server supports it, then calls GetErrorInfo.

In practice, the _com_error class wraps this. Here’s the pattern:

#include <comdef.h>  // Declares _com_error

inline void throw_if_fail(HRESULT hr)
{
    if (FAILED(hr))
    {
        throw _com_error(hr);
    }
}

void ShowDialog()
{
    try
    {
        CComPtr<IFileOpenDialog> pFileOpen;
        throw_if_fail(CoCreateInstance(__uuidof(FileOpenDialog), NULL, 
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFileOpen)));

        throw_if_fail(pFileOpen->Show(NULL));

        CComPtr<IShellItem> pItem;
        throw_if_fail(pFileOpen->GetResult(&pItem));

        // Use pItem (not shown).
    }
    catch (_com_error err)
    {
        // Handle error.
    }
}

References