Improve OleRun error reporting

1. Pass its error message up the call stack as the exception's message.
2. In case of REGDB_E_CLASSNOTREG, also obtain the object's class name
   and append it to the message.
3. Show this information in the message displayed for OLE activation
   error.

This introduces a new SetExtendedMessage method in SfxErrorContext to
store extra information for specific errors.

Change-Id: Id3863276266d992ae407fbfa5568acf5c57aa96f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157372
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski 2023-09-28 15:15:53 +03:00
parent 608c35665b
commit 11aa86140e
4 changed files with 41 additions and 3 deletions

View File

@ -24,6 +24,7 @@
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/embed/WrongStateException.hpp>
#include <com/sun/star/embed/UnreachableStateException.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/io/TempFile.hpp>
@ -883,10 +884,29 @@ void OleComponent::RunObject()
if ( FAILED( hr ) )
{
OUString error = WindowsErrorStringFromHRESULT(hr);
if ( hr == REGDB_E_CLASSNOTREG )
throw embed::UnreachableStateException(); // the object server is not installed
{
if (auto pOleObj
= m_pNativeImpl->m_pObj.QueryInterface<IOleObject>(sal::systools::COM_QUERY))
{
LPOLESTR lpUserType = nullptr;
if (SUCCEEDED(pOleObj->GetUserType(USERCLASSTYPE_FULL, &lpUserType)))
{
error += OUString::Concat("\n") + o3tl::toU(lpUserType);
sal::systools::COMReference<IMalloc> pMalloc;
hr = CoGetMalloc(1, &pMalloc); // if fails there will be a memory leak
SAL_WARN_IF(FAILED(hr) || !pMalloc, "embeddedobj.ole", "CoGetMalloc() failed");
if (pMalloc)
pMalloc->Free(lpUserType);
}
}
throw embed::UnreachableStateException(
error, getXWeak(), -1,
css::embed::EmbedStates::RUNNING); // the object server is not installed
}
else
throw io::IOException();
throw io::IOException(error, getXWeak());
}
}
}

View File

@ -23,6 +23,8 @@
#include <svtools/svtresid.hxx>
#include <vcl/errinf.hxx>
#include <unordered_map>
typedef std::pair<TranslateId, ErrCode> ErrMsgCode;
SVT_DLLPUBLIC extern const ErrMsgCode RID_ERRHDL[];
SVT_DLLPUBLIC extern const ErrMsgCode RID_ERRCTX[];
@ -40,11 +42,14 @@ public:
const ErrMsgCode* pIds = nullptr, const std::locale& rResLocaleP = SvtResLocale());
bool GetString(ErrCode nErrId, OUString &rStr) override;
void SetExtendedMessage(ErrCode nErrId, const OUString& rStr);
private:
sal_uInt16 nCtxId;
const ErrMsgCode* pIds;
std::locale aResLocale;
OUString aArg1;
std::unordered_map<sal_uInt32, OUString> m_extMessages;
};
class SVT_DLLPUBLIC SfxErrorHandler : private ErrorHandler

View File

@ -970,7 +970,7 @@ ErrCode SfxInPlaceClient::DoVerb(sal_Int32 nVerb)
m_xImp->m_xObject->doVerb( nVerb );
}
catch ( embed::UnreachableStateException& )
catch ( embed::UnreachableStateException& e )
{
if (nVerb == embed::EmbedVerbs::MS_OLEVERB_PRIMARY || nVerb == embed::EmbedVerbs::MS_OLEVERB_OPEN || nVerb == embed::EmbedVerbs::MS_OLEVERB_SHOW)
{
@ -997,6 +997,7 @@ ErrCode SfxInPlaceClient::DoVerb(sal_Int32 nVerb)
{
TOOLS_WARN_EXCEPTION("embeddedobj", "SfxInPlaceClient::DoVerb: -9 fallback path");
nError = ERRCODE_SO_GENERALERROR;
aEc.SetExtendedMessage(ERRCODE_SO_GENERALERROR, e.Message);
}
}
}

View File

@ -293,7 +293,19 @@ bool SfxErrorContext::GetString(ErrCode nErrId, OUString &rStr)
}
}
if (bRet)
if (auto it = m_extMessages.find(sal_uInt32(nErrId)); it != m_extMessages.end())
rStr += "\n" + it->second;
return bRet;
}
void SfxErrorContext::SetExtendedMessage(ErrCode nErrId, const OUString& rStr)
{
if (rStr.isEmpty())
m_extMessages.erase(sal_uInt32(nErrId));
else
m_extMessages[sal_uInt32(nErrId)] = rStr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */