__declspec(noreturn) void ThrowComError(HRESULT hr, LPOLESTR err) { ICreateErrorInfoPtr errCreate; if (SUCCEEDED(CreateErrorInfo(&errCreate)) && SUCCEEDED(errCreate->SetDescription(const_cast<wchar_t*>(err))) && SUCCEEDED(errCreate->SetSource(const_cast<wchar_t*>(g_COCLASS_PROGIDW))) ) { IErrorInfoPtr errorInfo = errCreate; throw _com_error(hr, errorInfo.Detach()); } throw _com_error(hr); }
/*---------------------------------------------------------------------------------------------- This method is called by CheckHr (with punk and iid null) or CheckExtHr, after confirming that hrErr is an error HRESULT. It first confirms that there is an error info object available. If punk and iid are supplied, it further checks that the error info object is relevant to that object and interface. If a relevant error object is available, and it indicates that a programming error has occurred, and its Description does not yet contain a stack dump, we add one if possible. Then we ThrowHr, with a special HelpId to indicate that HandleThrowable need not generate a new error object. If no relevant error object is available, we generate a stack dump and treat the problem as an internal error. ----------------------------------------------------------------------------------------------*/ void CheckHrCore(HRESULT hrErr) { IErrorInfoPtr qerrinfo; ::GetErrorInfo(0, &qerrinfo); // This clears the system wide error info if (!qerrinfo) { // We didn't have any (relevant) error info ThrowInternalError(hrErr); } SmartBstr sbstrDesc; qerrinfo->GetDescription(&sbstrDesc); // We have an error info object, and presume that it is relevant. // If it indicates a programming error, and doesn't already contain a // stack dump, try to add one. if (hrErr == E_INVALIDARG || hrErr == E_POINTER || hrErr == E_UNEXPECTED) { // If so look for stack dump type info. std::wstring strDesc = sbstrDesc; if (!wcsstr(strDesc.c_str(), ThrowableSd::MoreSep())) { // no stack there, so add one DumpStackHere("Error was detected by CheckHr here:\r\n"); StrUni stuDescNew; stuDescNew.Format(L"%s%s%S", sbstrDesc.Chars(), ThrowableSd::MoreSep(), StackDumper::GetDump()); sbstrDesc.Append(const_cast<OLECHAR *>(stuDescNew.Chars())); // Now modify the error info ICreateErrorInfoPtr qcerrinfo; if (SUCCEEDED(qerrinfo->QueryInterface(IID_ICreateErrorInfo, (LPVOID FAR*) &qcerrinfo))) qcerrinfo->SetDescription(sbstrDesc); } } // Throw an error indicating there is already a good error object in place. ThrowHr(hrErr, sbstrDesc.Bstr(), -1, qerrinfo); }
bool AOErr(HRESULT hr, std::string desc) { IErrorInfoPtr ipErrorInfo = NULL; ::GetErrorInfo(NULL, &ipErrorInfo); if (ipErrorInfo) { CComBSTR comErrDesc; ipErrorInfo->GetDescription(&comErrDesc); CW2A errMsg(comErrDesc); CPLError( CE_Failure, CPLE_AppDefined, "AO Error: %s HRESULT:%d COM_ERROR:%s", desc.c_str(), hr, errMsg ); ::SetErrorInfo(NULL, NULL); } else { CPLError( CE_Failure, CPLE_AppDefined, "AO Error: %s HRESULT:%d", desc.c_str(), hr); } return false; }