IErrorInfo *COMException::GetErrorInfo() { LIMITED_METHOD_CONTRACT; IErrorInfo *pErrorInfo = m_pErrorInfo; if (pErrorInfo != NULL) pErrorInfo->AddRef(); return pErrorInfo; }
/* 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); }