include/xmloff/xmlerror.hxx     |    4 +++-
 include/xmloff/xmlexp.hxx       |    4 ++++
 sw/source/filter/xml/wrtxml.cxx |    7 +++++++
 xmloff/source/core/xmlerror.cxx |   26 +++++++++++++++++++++++++-
 xmloff/source/core/xmlexp.cxx   |    7 ++++++-
 xmloff/source/core/xmlimp.cxx   |    2 +-
 6 files changed, 46 insertions(+), 4 deletions(-)

New commits:
commit ccd010346cb2afc6f8c9d9880c03e82ba5fceb9a
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Mar 12 11:45:22 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 12 17:18:28 2025 +0100

    cool#11320 xmloff lok: improve error reporting
    
    When processing a report on failed ODF save, it can be tricky to find
    reproduction steps. A typical source of errors is some uncaught
    exception. Currently we just report which stream failed to save:
    
    0x70c23(Error Area:Sw Class:Write Code:35) arg1=SfxBaseModel::storeSelf: 
0x70c23(Error Area:Sw Class:Write Code:35) arg1=styles.xml at 
sfx2/source/doc/sfxbasemodel.cxx:1735
    
    Improve this to also report what would appear on stderr in a dbgutil
    build:
    
    com.sun.star.lang.IllegalArgumentException: "SwXMLExport::exportTheme() 
failed at sw/source/filter/xml/xmlfmte.cxx:189"
    
    In case e.g. the theme export throws an exception for testing purposes.
    
    Change-Id: I85ec1ac4f932851401aa3b25a753219eb20638a4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182831
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/xmloff/xmlerror.hxx b/include/xmloff/xmlerror.hxx
index 027639e6ab53..6bea08cb1636 100644
--- a/include/xmloff/xmlerror.hxx
+++ b/include/xmloff/xmlerror.hxx
@@ -94,6 +94,7 @@ namespace com::sun::star {
 }
 
 class ErrorRecord;
+namespace vcl { class ILibreOfficeKitNotifier; }
 
 /**
  * The XMLErrors is used to collect all errors and warnings that occur
@@ -105,10 +106,11 @@ class XMLErrors
     typedef ::std::vector<ErrorRecord> ErrorList;
 
     ErrorList m_aErrors;  /// list of error records
+    vcl::ILibreOfficeKitNotifier* mpNotifier;
 
 public:
 
-    XMLErrors();
+    XMLErrors(vcl::ILibreOfficeKitNotifier* pNotifier);
     ~XMLErrors();
 
     /// add a new entry to the list of error messages
diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index 9dafd90cda3e..0af38ec1685d 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -86,6 +86,7 @@ namespace com::sun::star {
 namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; }
 
 namespace model { class Theme; }
+namespace vcl { class ILibreOfficeKitNotifier; }
 
 enum class SvXMLExportFlags {
     NONE                     = 0,
@@ -150,6 +151,7 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public 
cppu::WeakImplHelper<
     std::unique_ptr<XMLEventExport> mpEventExport;
     std::unique_ptr<XMLImageMapExport> mpImageMapExport;
     std::unique_ptr<XMLErrors>  mpXMLErrors;
+    vcl::ILibreOfficeKitNotifier* mpNotifier = nullptr;
 
     const enum ::xmloff::token::XMLTokenEnum meClass;
     SAL_DLLPRIVATE void InitCtor_();
@@ -554,6 +556,8 @@ public:
 
     /// Get clamped mimetype for image export (empty if none)
     OUString const & GetImageFilterName() const;
+
+    void SetLibreOfficeKitNotifier(vcl::ILibreOfficeKitNotifier* pNotifier);
 };
 
 inline rtl::Reference< XMLTextParagraphExport > const & 
SvXMLExport::GetTextParagraphExport()
diff --git a/sw/source/filter/xml/wrtxml.cxx b/sw/source/filter/xml/wrtxml.cxx
index 6dae1b99f12b..01d0bd2b682e 100644
--- a/sw/source/filter/xml/wrtxml.cxx
+++ b/sw/source/filter/xml/wrtxml.cxx
@@ -62,6 +62,8 @@
 
 #include <comphelper/documentconstants.hxx>
 #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
+#include <xmloff/xmlexp.hxx>
+#include <sfx2/viewsh.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -573,6 +575,11 @@ bool SwXMLWriter::WriteThroughComponent(
     // filter!
     SAL_INFO( "sw.filter", "call filter()" );
     uno::Reference<XFilter> xFilter( xExporter, UNO_QUERY );
+    auto pFilter = dynamic_cast<SvXMLExport*>(xFilter.get());
+    if (pFilter)
+    {
+        pFilter->SetLibreOfficeKitNotifier(SfxViewShell::Current());
+    }
     return xFilter->filter( rMediaDesc );
 }
 
diff --git a/xmloff/source/core/xmlerror.cxx b/xmloff/source/core/xmlerror.cxx
index 75315f78e077..6079797e823b 100644
--- a/xmloff/source/core/xmlerror.cxx
+++ b/xmloff/source/core/xmlerror.cxx
@@ -27,6 +27,10 @@
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/Sequence.hxx>
 #include <rtl/ustrbuf.hxx>
+#include <comphelper/lok.hxx>
+#include <tools/json_writer.hxx>
+#include <vcl/IDialogRenderable.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 using ::com::sun::star::uno::Any;
 using ::com::sun::star::uno::Sequence;
@@ -78,7 +82,8 @@ ErrorRecord::ErrorRecord( sal_Int32 nID, const 
Sequence<OUString>& rParams,
 {
 }
 
-XMLErrors::XMLErrors()
+XMLErrors::XMLErrors(vcl::ILibreOfficeKitNotifier* pNotifier)
+    : mpNotifier(pNotifier)
 {
 }
 
@@ -98,6 +103,25 @@ void XMLErrors::AddRecord(
     m_aErrors.emplace_back( nId, rParams, rExceptionMessage,
                                     nRow, nColumn, rPublicId, rSystemId );
 
+    if (comphelper::LibreOfficeKit::isActive() && mpNotifier)
+    {
+        // The outer error is logged in sfx2, mentioning just the stream name. 
Also log here the
+        // inner error, which potentially contains the location of an uncaught 
exception.
+        sal_Int32 nFlags = (nId & XMLERROR_MASK_FLAG);
+        if (nFlags & (XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | 
XMLERROR_API))
+        {
+            tools::JsonWriter aWriter;
+            {
+                aWriter.put("classification", "error");
+                aWriter.put("code", "");
+                aWriter.put("kind", "");
+                aWriter.put("cmd", "");
+                aWriter.put("message", rExceptionMessage);
+            }
+            mpNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_ERROR, 
aWriter.finishAndGetAsOString());
+        }
+    }
+
 #ifdef DBG_UTIL
 
     // give detailed assertion on this message
diff --git a/xmloff/source/core/xmlexp.cxx b/xmloff/source/core/xmlexp.cxx
index 2cec3eb32f89..4d77d6bc26db 100644
--- a/xmloff/source/core/xmlexp.cxx
+++ b/xmloff/source/core/xmlexp.cxx
@@ -2286,7 +2286,7 @@ void SvXMLExport::SetError(
 
     // create error list on demand
     if ( mpXMLErrors == nullptr )
-        mpXMLErrors.reset( new XMLErrors() );
+        mpXMLErrors.reset( new XMLErrors(mpNotifier) );
 
     // save error information
     mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator );
@@ -2442,6 +2442,11 @@ OUString const & SvXMLExport::GetImageFilterName() const
     return msImgFilterName;
 }
 
+void SvXMLExport::SetLibreOfficeKitNotifier(vcl::ILibreOfficeKitNotifier* 
pNotifier)
+{
+    mpNotifier = pNotifier;
+}
+
 void SvXMLElementExport::StartElement(
     const sal_uInt16 nPrefixKey,
     const OUString& rLName,
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 3c405d21a0d0..94bf7e41b7a7 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1784,7 +1784,7 @@ void SvXMLImport::SetError(
 {
     // create error list on demand
     if ( !mpXMLErrors )
-        mpXMLErrors = std::make_unique<XMLErrors>();
+        mpXMLErrors = std::make_unique<XMLErrors>(nullptr);
 
     // save error information
     // use document locator (if none supplied)

Reply via email to