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;
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

View File

@ -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()

View File

@ -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 );
}

View File

@ -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

View File

@ -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,

View File

@ -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)