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 <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna
2025-03-12 11:45:22 +01:00
parent b320ade8f9
commit ccd010346c
6 changed files with 46 additions and 4 deletions

View File

@@ -94,6 +94,7 @@ namespace com::sun::star {
} }
class ErrorRecord; class ErrorRecord;
namespace vcl { class ILibreOfficeKitNotifier; }
/** /**
* The XMLErrors is used to collect all errors and warnings that occur * The XMLErrors is used to collect all errors and warnings that occur
@@ -105,10 +106,11 @@ class XMLErrors
typedef ::std::vector<ErrorRecord> ErrorList; typedef ::std::vector<ErrorRecord> ErrorList;
ErrorList m_aErrors; /// list of error records ErrorList m_aErrors; /// list of error records
vcl::ILibreOfficeKitNotifier* mpNotifier;
public: public:
XMLErrors(); XMLErrors(vcl::ILibreOfficeKitNotifier* pNotifier);
~XMLErrors(); ~XMLErrors();
/// add a new entry to the list of error messages /// add a new entry to the list of error messages

View File

@@ -86,6 +86,7 @@ namespace com::sun::star {
namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; } namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; }
namespace model { class Theme; } namespace model { class Theme; }
namespace vcl { class ILibreOfficeKitNotifier; }
enum class SvXMLExportFlags { enum class SvXMLExportFlags {
NONE = 0, NONE = 0,
@@ -150,6 +151,7 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public cppu::WeakImplHelper<
std::unique_ptr<XMLEventExport> mpEventExport; std::unique_ptr<XMLEventExport> mpEventExport;
std::unique_ptr<XMLImageMapExport> mpImageMapExport; std::unique_ptr<XMLImageMapExport> mpImageMapExport;
std::unique_ptr<XMLErrors> mpXMLErrors; std::unique_ptr<XMLErrors> mpXMLErrors;
vcl::ILibreOfficeKitNotifier* mpNotifier = nullptr;
const enum ::xmloff::token::XMLTokenEnum meClass; const enum ::xmloff::token::XMLTokenEnum meClass;
SAL_DLLPRIVATE void InitCtor_(); SAL_DLLPRIVATE void InitCtor_();
@@ -554,6 +556,8 @@ public:
/// Get clamped mimetype for image export (empty if none) /// Get clamped mimetype for image export (empty if none)
OUString const & GetImageFilterName() const; OUString const & GetImageFilterName() const;
void SetLibreOfficeKitNotifier(vcl::ILibreOfficeKitNotifier* pNotifier);
}; };
inline rtl::Reference< XMLTextParagraphExport > const & SvXMLExport::GetTextParagraphExport() inline rtl::Reference< XMLTextParagraphExport > const & SvXMLExport::GetTextParagraphExport()

View File

@@ -62,6 +62,8 @@
#include <comphelper/documentconstants.hxx> #include <comphelper/documentconstants.hxx>
#include <com/sun/star/rdf/XDocumentMetadataAccess.hpp> #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;
using namespace ::com::sun::star::uno; using namespace ::com::sun::star::uno;
@@ -573,6 +575,11 @@ bool SwXMLWriter::WriteThroughComponent(
// filter! // filter!
SAL_INFO( "sw.filter", "call filter()" ); SAL_INFO( "sw.filter", "call filter()" );
uno::Reference<XFilter> xFilter( xExporter, UNO_QUERY ); uno::Reference<XFilter> xFilter( xExporter, UNO_QUERY );
auto pFilter = dynamic_cast<SvXMLExport*>(xFilter.get());
if (pFilter)
{
pFilter->SetLibreOfficeKitNotifier(SfxViewShell::Current());
}
return xFilter->filter( rMediaDesc ); return xFilter->filter( rMediaDesc );
} }

View File

@@ -27,6 +27,10 @@
#include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/Sequence.hxx>
#include <rtl/ustrbuf.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::Any;
using ::com::sun::star::uno::Sequence; 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, m_aErrors.emplace_back( nId, rParams, rExceptionMessage,
nRow, nColumn, rPublicId, rSystemId ); 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 #ifdef DBG_UTIL
// give detailed assertion on this message // give detailed assertion on this message

View File

@@ -2286,7 +2286,7 @@ void SvXMLExport::SetError(
// create error list on demand // create error list on demand
if ( mpXMLErrors == nullptr ) if ( mpXMLErrors == nullptr )
mpXMLErrors.reset( new XMLErrors() ); mpXMLErrors.reset( new XMLErrors(mpNotifier) );
// save error information // save error information
mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator ); mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator );
@@ -2442,6 +2442,11 @@ OUString const & SvXMLExport::GetImageFilterName() const
return msImgFilterName; return msImgFilterName;
} }
void SvXMLExport::SetLibreOfficeKitNotifier(vcl::ILibreOfficeKitNotifier* pNotifier)
{
mpNotifier = pNotifier;
}
void SvXMLElementExport::StartElement( void SvXMLElementExport::StartElement(
const sal_uInt16 nPrefixKey, const sal_uInt16 nPrefixKey,
const OUString& rLName, const OUString& rLName,

View File

@@ -1784,7 +1784,7 @@ void SvXMLImport::SetError(
{ {
// create error list on demand // create error list on demand
if ( !mpXMLErrors ) if ( !mpXMLErrors )
mpXMLErrors = std::make_unique<XMLErrors>(); mpXMLErrors = std::make_unique<XMLErrors>(nullptr);
// save error information // save error information
// use document locator (if none supplied) // use document locator (if none supplied)