embeddedobj/source/msole/olecomponent.cxx |   24 ++++++++++++++++++++++--
 include/svtools/ehdl.hxx                  |    5 +++++
 sfx2/source/view/ipclient.cxx             |    3 ++-
 svtools/source/misc/ehdl.cxx              |   12 ++++++++++++
 4 files changed, 41 insertions(+), 3 deletions(-)

New commits:
commit 11aa86140eaac3d1d67db1f337fc1c76a511778f
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Sep 28 15:15:53 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Sep 28 16:02:55 2023 +0200

    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.kagan...@collabora.com>

diff --git a/embeddedobj/source/msole/olecomponent.cxx 
b/embeddedobj/source/msole/olecomponent.cxx
index fcd659e369a3..f981a4304656 100644
--- a/embeddedobj/source/msole/olecomponent.cxx
+++ b/embeddedobj/source/msole/olecomponent.cxx
@@ -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());
         }
     }
 }
diff --git a/include/svtools/ehdl.hxx b/include/svtools/ehdl.hxx
index d67f094f818e..78bcf1723dfe 100644
--- a/include/svtools/ehdl.hxx
+++ b/include/svtools/ehdl.hxx
@@ -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
diff --git a/sfx2/source/view/ipclient.cxx b/sfx2/source/view/ipclient.cxx
index 367d3070938b..260bdff77f34 100644
--- a/sfx2/source/view/ipclient.cxx
+++ b/sfx2/source/view/ipclient.cxx
@@ -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);
                         }
                     }
                 }
diff --git a/svtools/source/misc/ehdl.cxx b/svtools/source/misc/ehdl.cxx
index a2cd3ef63323..ef35b3975fca 100644
--- a/svtools/source/misc/ehdl.cxx
+++ b/svtools/source/misc/ehdl.cxx
@@ -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: */

Reply via email to