Error Object Example

The code in this example illustrates the use of error objects in OLE DB error handling.

////////////////////////////////////////////////////////////////////////
// myHandleResult
//
//    This function is called as part of the XCHECK_HR macro; it takes a
//    HRESULT, which is returned by the method called in the XCHECK_HR
//    macro, and the file and line number where the method call was made.
//    If the method call failed, this function attempts to get and display
//    the extended error information for the call from the IErrorInfo,
//    IErrorRecords, and ISQLErrorInfo interfaces.
//
////////////////////////////////////////////////////////////////////////
HRESULT myHandleResult
    (
    HRESULT                    hrReturned,
    LPCWSTR                    pwszFile,
    ULONG                      ulLine
    )
{
    HRESULT                    hr;
    IErrorInfo *              pIErrorInfo                    = NULL;
    IErrorRecords *           pIErrorRecords                 = NULL;
    ULONG                     cRecords;
    ULONG                     iErr;

    // If the method called as part of the XCHECK_HR macro failed,
    // we will attempt to get extended error information for the call
    if( FAILED(hrReturned) )
    {
        // Obtain the current Error object, if any, by using the
        // OLE Automation GetErrorInfo function, which will give
        // us back an IErrorInfo interface pointer if successful
        hr = GetErrorInfo(0, &pIErrorInfo);

        // We've got the IErrorInfo interface pointer on the Error object
        if( SUCCEEDED(hr) && pIErrorInfo )
        {
            // OLE DB extends the OLE Automation error model by allowing
            // Error objects to support the IErrorRecords interface; this
            // interface can expose information on multiple errors.
            hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, 
                        (void**)&pIErrorRecords);
            if( SUCCEEDED(hr) )
            {
                // Get the count of error records from the object
                CHECK_HR(hr = pIErrorRecords->GetRecordCount(&cRecords));
                
                // Loop through the set of error records and
                // display the error information for each one
                for( iErr = 0; iErr < cRecords; iErr++ )
                {
                    myDisplayErrorRecord(hrReturned, iErr, pIErrorRecords,
                        pwszFile, ulLine);
                }
            }
            // The object didn't support IErrorRecords; display
            // the error information for this single error
            else
            {
                myDisplayErrorInfo(hrReturned, pIErrorInfo, pwszFile, ulLine);
            }
        }
        // There was no Error object, so just display the HRESULT to the user
        else
        {
            wprintf(L"\nNo Error Info posted; HResult: 0x%08x\n"
                L"File: %s, Line: %d\n", hrReturned, pwszFile, ulLine);
        }
    }

CLEANUP:
    if( pIErrorInfo )
        pIErrorInfo->Release();
    if( pIErrorRecords )
        pIErrorRecords->Release();
    return hrReturned;
}