// static void XPCThrower::ThrowCOMError(JSContext* cx, unsigned long COMErrorCode, nsresult rv, const EXCEPINFO * exception) { nsCAutoString msg; IErrorInfo * pError; const char * format; if(!nsXPCException::NameAndFormatForNSResult(rv, nsnull, &format)) format = ""; msg = format; #ifndef WINCE if(exception) { msg += static_cast<const char *> (_bstr_t(exception->bstrSource, false)); msg += " : "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode)); msg += " - "; msg += static_cast<const char *> (_bstr_t(exception->bstrDescription, false)); } else { // Get the current COM error object unsigned long result = GetErrorInfo(0, &pError); if(SUCCEEDED(result) && pError) { // Build an error message from the COM error object BSTR bstrSource = NULL; if(SUCCEEDED(pError->GetSource(&bstrSource)) && bstrSource) { _bstr_t src(bstrSource, false); msg += static_cast<const char *>(src); msg += " : "; } msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); BSTR bstrDesc = NULL; if(SUCCEEDED(pError->GetDescription(&bstrDesc)) && bstrDesc) { msg += " - "; _bstr_t desc(bstrDesc, false); msg += static_cast<const char *>(desc); } } else { // No error object, so just report the result msg += "COM Error Result = "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); } } #else // No error object, so just report the result msg += "COM Error Result = "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); #endif XPCThrower::BuildAndThrowException(cx, rv, msg.get()); }
/*---------------------------------------------------------------------------------------------- Static method to find a class factory (from the given CLSID) from all the class factories that are in the linked list. If the requested class factory is not found, *ppv is set to NULL and CLASS_E_CLASSNOTAVAILABLE is returned. ----------------------------------------------------------------------------------------------*/ HRESULT ModuleEntry::ModuleGetClassObject(REFCLSID clsid, REFIID iid, void ** ppv) { AssertPtrN(ppv); if (!ppv) return WarnHr(E_POINTER); *ppv = NULL; // This block of code is largely copied from the AssertNoErrorInfo method in throwable.h. // Here, however, we don't assert, but just dump a warning to the output window and // discard the spurious error info. This prevents asserts if Windows.Forms calls // a class factory (as it has been known to do) with spurious error info registered. #ifdef DEBUG IErrorInfo * pIErrorInfo = NULL; HRESULT hr = GetErrorInfo(0, &pIErrorInfo); Assert(SUCCEEDED(hr)); if(pIErrorInfo != NULL) { BSTR bstr; hr = pIErrorInfo->GetDescription(&bstr); Assert(SUCCEEDED(hr)); ::OutputDebugString(bstr); ::SysFreeString(bstr); hr = pIErrorInfo->GetSource(&bstr); Assert(SUCCEEDED(hr)); ::OutputDebugString(bstr); ::SysFreeString(bstr); pIErrorInfo->Release(); } #endif ModuleEntry * pme; try { for (pme = s_pmeFirst; pme; pme = pme->m_pobjNext) { AssertPtr(pme); pme->GetClassFactory(clsid, iid, ppv); if (*ppv) return S_OK; } } catch (const Throwable & thr) { return thr.Error(); } catch (...) { return WarnHr(E_FAIL); } return CLASS_E_CLASSNOTAVAILABLE; }
/* Determines whether we can use the error information from the source object and if so, throws that as an error. If serr is non-NULL, then the error is not thrown in R but a COMSErrorInfo object is returned with the information in it. */ HRESULT checkErrorInfo(IUnknown *obj, HRESULT status, SEXP *serr) { HRESULT hr; ISupportErrorInfo *info; fprintf(stderr, "<checkErrorInfo> %X \n", (unsigned int) status); if(serr) *serr = NULL; hr = obj->QueryInterface(IID_ISupportErrorInfo, (void **)&info); if(hr != S_OK) { fprintf(stderr, "No support for ISupportErrorInfo\n");fflush(stderr); return(hr); } info->AddRef(); hr = info->InterfaceSupportsErrorInfo(IID_IDispatch); info->Release(); if(hr != S_OK) { fprintf(stderr, "No support for InterfaceSupportsErrorInfo\n");fflush(stderr); return(hr); } IErrorInfo *errorInfo; hr = GetErrorInfo(0L, &errorInfo); if(hr != S_OK) { /* fprintf(stderr, "GetErrorInfo failed\n");fflush(stderr); */ COMError(status); return(hr); } /* So there is some information for us. Use it. */ SEXP klass, ans, tmp; BSTR ostr; char *str; errorInfo->AddRef(); if(serr) { PROTECT(klass = MAKE_CLASS("SCOMErrorInfo")); PROTECT(ans = NEW(klass)); PROTECT(tmp = NEW_CHARACTER(1)); errorInfo->GetSource(&ostr); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(FromBstr(ostr))); SET_SLOT(ans, Rf_install("source"), tmp); UNPROTECT(1); PROTECT(tmp = NEW_CHARACTER(1)); errorInfo->GetDescription(&ostr); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(str = FromBstr(ostr))); SET_SLOT(ans, Rf_install("description"), tmp); UNPROTECT(1); PROTECT(tmp = NEW_NUMERIC(1)); NUMERIC_DATA(tmp)[0] = status; SET_SLOT(ans, Rf_install("status"), tmp); *serr = ans; UNPROTECT(3); errorInfo->Release(); PROBLEM "%s", str WARN; } else { errorInfo->GetDescription(&ostr); str = FromBstr(ostr); errorInfo->GetSource(&ostr); errorInfo->Release(); PROBLEM "%s (%s)", str, FromBstr(ostr) ERROR; } return(hr); }
/******************************************************************** SqlGetErrorInfo - gets error information from the last SQL function call NOTE: pbstrErrorSource and pbstrErrorDescription are optional ********************************************************************/ extern "C" HRESULT DAPI SqlGetErrorInfo( __in IUnknown* pObjectWithError, __in REFIID IID_InterfaceWithError, __in DWORD dwLocaleId, __out_opt BSTR* pbstrErrorSource, __out_opt BSTR* pbstrErrorDescription ) { HRESULT hr = S_OK; Assert(pObjectWithError); // interfaces needed to extract error information out ISupportErrorInfo* pISupportErrorInfo = NULL; IErrorInfo* pIErrorInfoAll = NULL; IErrorRecords* pIErrorRecords = NULL; IErrorInfo* pIErrorInfoRecord = NULL; // only ask for error information if the interface supports it. hr = pObjectWithError->QueryInterface(IID_ISupportErrorInfo,(void**)&pISupportErrorInfo); ExitOnFailure(hr, "No error information was found for object."); hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_InterfaceWithError); ExitOnFailure(hr, "InterfaceWithError is not supported for object with error"); // ignore the return of GetErrorInfo it can succeed and return a NULL pointer in pIErrorInfoAll anyway hr = ::GetErrorInfo(0, &pIErrorInfoAll); ExitOnFailure(hr, "failed to get error info"); if (S_OK == hr && pIErrorInfoAll) { // see if it's a valid OLE DB IErrorInfo interface that exposes a list of records hr = pIErrorInfoAll->QueryInterface(IID_IErrorRecords, (void**)&pIErrorRecords); if (SUCCEEDED(hr)) { ULONG cErrors = 0; pIErrorRecords->GetRecordCount(&cErrors); // get the error information for each record for (ULONG i = 0; i < cErrors; ++i) { hr = pIErrorRecords->GetErrorInfo(i, dwLocaleId, &pIErrorInfoRecord); if (SUCCEEDED(hr)) { if (pbstrErrorSource) { pIErrorInfoRecord->GetSource(pbstrErrorSource); } if (pbstrErrorDescription) { pIErrorInfoRecord->GetDescription(pbstrErrorDescription); } ReleaseNullObject(pIErrorInfoRecord); break; // TODO: return more than one error in the future! } } ReleaseNullObject(pIErrorRecords); } else // we have a simple error record { if (pbstrErrorSource) { pIErrorInfoAll->GetSource(pbstrErrorSource); } if (pbstrErrorDescription) { pIErrorInfoAll->GetDescription(pbstrErrorDescription); } } } else { hr = E_NOMOREITEMS; } LExit: ReleaseObject(pIErrorInfoRecord); ReleaseObject(pIErrorRecords); ReleaseObject(pIErrorInfoAll); ReleaseObject(pISupportErrorInfo); return hr; }
// Info: Gets both unrestricted and restricted error info // Parameters: scriptContext - the script context // pexcepinfo - the exception info of the error (unrestricted) // proerrstr - the winrt specific error strings (restricted) // pperrinfo - the IErrorInfo object // Returns: Failed HRESULT - if GetErrorInfo or QI fail // Success - otherwise HRESULT JavascriptErrorDebug::GetExcepAndErrorInfo(ScriptContext* scriptContext, HRESULT hrReturned, EXCEPINFO *pexcepinfo, RestrictedErrorStrings * proerrstr, IErrorInfo ** pperrinfo) { HRESULT hr; HRESULT hrResult; bool errorInfoMatch = false; memset(pexcepinfo, 0, sizeof(*pexcepinfo)); memset(proerrstr, 0, sizeof(*proerrstr)); *pperrinfo = nullptr; // GetErrorInfo returns S_FALSE if there is no rich error info // and S_OK if there is. IErrorInfo * perrinfo; if(NOERROR != (hr = GetErrorInfo(0L, &perrinfo))) { return hr; } // Fill Exception info perrinfo->GetSource(&pexcepinfo->bstrSource); perrinfo->GetDescription(&pexcepinfo->bstrDescription); perrinfo->GetHelpFile(&pexcepinfo->bstrHelpFile); perrinfo->GetHelpContext(&pexcepinfo->dwHelpContext); // Initialize restricted strings proerrstr->restrictedErrStr = nullptr; proerrstr->referenceStr = nullptr; proerrstr->capabilitySid = nullptr; BSTR bstrErr = nullptr; BSTR bstrRestrictedErr = nullptr; BSTR bstrCapabilitySid = nullptr; BSTR bstrReference = nullptr; IRestrictedErrorInfo * pROErrorInfo = nullptr; _Exception * pCLRException = nullptr; hr = perrinfo->QueryInterface(__uuidof(IRestrictedErrorInfo), reinterpret_cast<void**>(&pROErrorInfo)); if (SUCCEEDED(hr)) { // Get restricted error strings from IRestrictedErrorInfo HRESULT hrErr = S_OK; hrResult = pROErrorInfo->GetErrorDetails(&bstrErr, &hrErr, &bstrRestrictedErr, &bstrCapabilitySid); if (SUCCEEDED(hrResult)) { errorInfoMatch = (hrErr == hrReturned); if (errorInfoMatch) { if (nullptr != bstrRestrictedErr) { proerrstr->restrictedErrStr = bstrRestrictedErr; bstrRestrictedErr = nullptr; } if (nullptr != bstrCapabilitySid) { proerrstr->capabilitySid = bstrCapabilitySid; bstrCapabilitySid = nullptr; } } } hrResult = pROErrorInfo->GetReference(&bstrReference); if (SUCCEEDED(hrResult) && errorInfoMatch) { if (nullptr != bstrReference) { proerrstr->referenceStr = bstrReference; bstrReference = nullptr; } } } else { hr = perrinfo->QueryInterface(__uuidof(_Exception), reinterpret_cast<void**>(&pCLRException)); if(FAILED(hr)) { perrinfo->Release(); return hr; } hrResult = pCLRException->get_Message(&bstrRestrictedErr); if (SUCCEEDED(hrResult)) { errorInfoMatch = true; if (nullptr != bstrRestrictedErr) { proerrstr->restrictedErrStr = bstrRestrictedErr; bstrRestrictedErr = nullptr; } } } if (nullptr != bstrErr) { SysFreeString(bstrErr); bstrErr = nullptr; } if (nullptr != bstrRestrictedErr) { SysFreeString(bstrRestrictedErr); bstrRestrictedErr = nullptr; } if (nullptr != bstrCapabilitySid) { SysFreeString(bstrCapabilitySid); bstrCapabilitySid = nullptr; } if (nullptr != bstrReference) { SysFreeString(bstrReference); bstrReference = nullptr; } if (!errorInfoMatch) { if (nullptr != pexcepinfo->bstrSource) { SysFreeString(pexcepinfo->bstrSource); pexcepinfo->bstrSource = nullptr; } if (nullptr != pexcepinfo->bstrDescription) { SysFreeString(pexcepinfo->bstrDescription); pexcepinfo->bstrDescription = nullptr; } if (nullptr != pexcepinfo->bstrHelpFile) { SysFreeString(pexcepinfo->bstrHelpFile); pexcepinfo->bstrHelpFile = nullptr; } perrinfo->Release(); perrinfo = nullptr; hr = S_FALSE; } if (nullptr != pROErrorInfo) { pROErrorInfo->Release(); } if (nullptr != pCLRException) { pCLRException->Release(); } *pperrinfo = perrinfo; return hr; }
/* * Generic COM error reporting function. */ static void comReportError(bpContext *ctx, HRESULT hrErr) { IErrorInfo *pErrorInfo; BSTR pSource = NULL; BSTR pDescription = NULL; HRESULT hr; char *source, *description; /* * See if there is anything to report. */ hr = GetErrorInfo(0, &pErrorInfo); if (hr == S_FALSE) { return; } /* * Get the description of the COM error. */ hr = pErrorInfo->GetDescription(&pDescription); if (!SUCCEEDED (hr)) { pErrorInfo->Release(); return; } /* * Get the source of the COM error. */ hr = pErrorInfo->GetSource(&pSource); if (!SUCCEEDED (hr)) { SysFreeString(pDescription); pErrorInfo->Release(); return; } /* * Convert windows BSTR to normal strings. */ source = BSTR_2_str(pSource); description = BSTR_2_str(pDescription); if (source && description) { Jmsg(ctx, M_FATAL, "%s(x%X): %s\n", source, hrErr, description); Dmsg(ctx, dbglvl, "%s(x%X): %s\n", source, hrErr, description); } if (source) { free(source); } if (description) { free(description); } /* * Generic cleanup (free the description and source as those are returned in * dynamically allocated memory by the COM routines.) */ SysFreeString(pSource); SysFreeString(pDescription); pErrorInfo->Release(); }
//Changed from //ms-help://MS.SSC.v35/MS.SSC.v35.EN/ssctechref/html/a25fafe1-e90a-4545-8836-749dd44135c0.htm CString SqlCeHelper::GetErrorsMessage() { static CString sErrIErrorInfo = L"IErrorInfo interface"; static CString sErrIErrorRecords = L"IErrorRecords interface"; static CString sErrRecordCount = L"error record count"; static CString sErrInfo = L"ERRORINFO structure"; static CString sErrStandardInfo = L"standard error info"; static CString sErrDescription = L"standard error description"; static CString sErrNoSource = L"error source"; HRESULT hr = S_OK; IErrorInfo *pIErrorInfo = NULL; IErrorRecords *pIErrorRecords = NULL; ERRORINFO errorInfo = { 0 }; IErrorInfo *pIErrorInfoRecord = NULL; CString message = L""; char str[255]; try { // This interface supports returning error information. // Get the error object from the system for the current // thread. hr = GetErrorInfo(0, &pIErrorInfo); if ( hr == S_FALSE ) { message = "No error occured."; return message; } if(FAILED(hr) || NULL == pIErrorInfo) throw sErrIErrorInfo; // The error records are retrieved from the IIErrorRecords // interface, which can be obtained from the IErrorInfo // interface. hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void **) &pIErrorRecords); if ( FAILED(hr) || NULL == pIErrorRecords ) throw sErrIErrorRecords; // The IErrorInfo interface is no longer required because // we have the IErrorRecords interface, relase it. pIErrorInfo->Release(); pIErrorInfo = NULL; ULONG ulNumErrorRecs = 0; // Determine the number of records in this error object hr = pIErrorRecords->GetRecordCount(&ulNumErrorRecs); if ( FAILED(hr) ) throw sErrRecordCount; // Loop over each error record in the error object to display // information about each error. Errors are returned. for (DWORD dwErrorIndex = 0; dwErrorIndex < ulNumErrorRecs; dwErrorIndex++) { // Retrieve basic error information for this error. hr = pIErrorRecords->GetBasicErrorInfo(dwErrorIndex, &errorInfo); if ( FAILED(hr) ) throw sErrInfo; TCHAR szCLSID[64] = { 0 }; TCHAR szIID[64] = { 0 }; TCHAR szDISPID[64] = { 0 }; StringFromGUID2(errorInfo.clsid, (LPOLESTR)szCLSID, sizeof(szCLSID)); StringFromGUID2(errorInfo.iid, (LPOLESTR)szIID, sizeof(szIID)); sprintf(str, "HRESULT = %lx\n", errorInfo.hrError); message += str; sprintf(str, "clsid = %S\n", szCLSID); message += str; sprintf(str, "iid = %S\n", szIID); message += str; sprintf(str, "dispid = %ld\n", errorInfo.dispid); message += str; sprintf(str, "Native Error Code = %lx\n", errorInfo.dwMinor); message += str; // Retrieve standard error information for this error. hr = pIErrorRecords->GetErrorInfo(dwErrorIndex, NULL, &pIErrorInfoRecord); if ( FAILED(hr) ) throw sErrStandardInfo; BSTR bstrDescriptionOfError; BSTR bstrSourceOfError; // Get the description of the error. hr = pIErrorInfoRecord->GetDescription( &bstrDescriptionOfError); if ( FAILED(hr) ) throw sErrDescription; sprintf(str, "Description = %S\n", bstrDescriptionOfError); message += str; // Get the source of the error. hr = pIErrorInfoRecord->GetSource(&bstrSourceOfError); if ( FAILED(hr) ) throw sErrNoSource; sprintf(str, "Description = %S\n", bstrSourceOfError); message += str; // This interface variable will be used the next time // though this loop. In the last error case this interface // is no longer needed so we must release it. if(NULL != pIErrorInfoRecord) pIErrorInfoRecord->Release(); pIErrorInfoRecord = NULL; } } catch( CString& szMsg ) { message = L"Failed to retrieve " + szMsg; } if( pIErrorInfoRecord ) pIErrorInfoRecord->Release(); if ( pIErrorInfo ) pIErrorInfo->Release(); if ( pIErrorRecords ) pIErrorRecords->Release(); return message; }
//////////////////////////////////////////////////////////////////////// // 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; }