Error Record Example

The code in this example shows how to process the contents of an error record.

////////////////////////////////////////////////////////////////////////
// myDisplayErrorRecord
//
// This function displays the error information for a single error
// record, including information from ISQLErrorInfo, if supported.
//
////////////////////////////////////////////////////////////////////////
HRESULT myDisplayErrorRecord
   (
   HRESULT              hrReturned,
   ULONG                iRecord,
   IErrorRecords *      pIErrorRecords,
   LPCWSTR              pwszFile,
   ULONG                ulLine)
{
   HRESULT              hr;
   IErrorInfo *         pIErrorInfo       = NULL;
   BSTR                 bstrDescription   = NULL;
   BSTR                 bstrSource        = NULL;
   BSTR                 bstrSQLInfo       = NULL;

   static LCID          lcid              = GetUserDefaultLCID();

   LONG                 lNativeError      = 0;
   ERRORINFO            ErrorInfo;

   // Get the IErrorInfo interface pointer for this error record.
   CHECK_HR(hr = pIErrorRecords->GetErrorInfo(iRecord, lcid,
            &pIErrorInfo));
   
   // Get the description of this error.
   CHECK_HR(hr = pIErrorInfo->GetDescription(&bstrDescription));
      
   // Get the source of this error.
   CHECK_HR(hr = pIErrorInfo->GetSource(&bstrSource));

   // Get the basic error information for this record.
   CHECK_HR(hr = pIErrorRecords->GetBasicErrorInfo(iRecord, &ErrorInfo));

   // If the error object supports ISQLErrorInfo, get this information.
   myGetSqlErrorInfo(iRecord, pIErrorRecords, &bstrSQLInfo,
                     &lNativeError);

   // Display the error information to the user.
   if( bstrSQLInfo )
   {
      wprintf(L"\nErrorRecord:  HResult: 0x%08x\nDescription: %s\n"
         L"SQLErrorInfo: %s\nSource: %s\nFile: %s, Line: %d\n",
         ErrorInfo.hrError,
         bstrDescription,
         bstrSQLInfo,
         bstrSource,
         pwszFile,
         ulLine);
   }
   else
   {
      wprintf(L"\nErrorRecord:  HResult: 0x%08x\nDescription: %s\n"
         L"Source: %s\nFile: %s, Line: %d\n",
         ErrorInfo.hrError,
         bstrDescription,
         bstrSource,
         pwszFile,
         ulLine);
   }

CLEANUP:
   if( pIErrorInfo )
      pIErrorInfo->Release();
   SysFreeString(bstrDescription);
   SysFreeString(bstrSource);
   SysFreeString(bstrSQLInfo);
   return hr;
}


////////////////////////////////////////////////////////////////////////
// myDisplayErrorInfo
//
// This function displays basic error information for an error object
// that doesn't support the IErrorRecords interface.
//
////////////////////////////////////////////////////////////////////////
HRESULT myDisplayErrorInfo
   (
   HRESULT           hrReturned,
   IErrorInfo *      pIErrorInfo,
   LPCWSTR           pwszFile,
   ULONG             ulLine)
{
   HRESULT           hr;
   BSTR              bstrDescription   = NULL;
   BSTR              bstrSource        = NULL;

   // Get the description of the error.
   CHECK_HR(hr = pIErrorInfo->GetDescription(&bstrDescription));
      
   // Get the source of the error--this will be the window title.
   CHECK_HR(hr = pIErrorInfo->GetSource(&bstrSource));

   // Display this error information.
   wprintf(L"\nErrorInfo: HResult: 0x%08x, Description: %s\nSource: %s\n"
            L"File: %s, Line: %d\n",
            hrReturned,
            bstrDescription,
            bstrSource,
            pwszFile,
            ulLine);

CLEANUP:
   SysFreeString(bstrDescription);
   SysFreeString(bstrSource);
   return hr;
}


////////////////////////////////////////////////////////////////////////
// myGetSqlErrorInfo
//
// If the error object supports ISQLErrorInfo, get the SQL error
// string and native error code for this error.
//
////////////////////////////////////////////////////////////////////////
HRESULT myGetSqlErrorInfo
   (
   ULONG                iRecord,
   IErrorRecords *      pIErrorRecords,
   BSTR *               pBstr,
   LONG *               plNativeError
   )
{
   HRESULT              hr;
   ISQLErrorInfo *      pISQLErrorInfo   = NULL;
   LONG                 lNativeError     = 0;

   // Attempt to get the ISQLErrorInfo interface for this error
   // record through GetCustomErrorObject. Note that ISQLErrorInfo
   // is not mandatory, so failure is acceptable here.
   CHECK_HR(hr = pIErrorRecords->GetCustomErrorObject(
            iRecord,                         // iRecord
            IID_ISQLErrorInfo,               // riid
            (IUnknown**)&pISQLErrorInfo));   // ppISQLErrorInfo

   // If we obtained the ISQLErrorInfo interface, get the SQL
   // error string and native error code for this error.
   if( pISQLErrorInfo )
      hr = pISQLErrorInfo->GetSQLInfo(pBstr, &lNativeError);

CLEANUP:
   if( plNativeError )
      *plNativeError = lNativeError;
   if( pISQLErrorInfo )
      pISQLErrorInfo->Release();
   return hr;
}