From 88d49cd98280bd65f042fb6c7f2490b16cfe5107 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 25 Feb 2021 12:23:13 +0100 Subject: [PATCH] Gui: [skip ci] improve exception handling: * handle all exceptions in Application::onLastWindowClosed because this method can be (indirectly) called from ~BaseView and would otherwise trigger std::terminate() * handle exceptions in PropertyEditor::closeTransaction() because when recomputing a document while closing it leaves the editor in a bad state --- src/Gui/Application.cpp | 25 ++++++++++------ src/Gui/propertyeditor/PropertyEditor.cpp | 36 +++++++++++++++++------ src/Gui/propertyeditor/PropertyEditor.h | 2 ++ 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 29561a9aca..f0b4c55c1d 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -970,8 +970,8 @@ void Application::slotResetEdit(const Gui::ViewProviderDocumentObject& vp) void Application::onLastWindowClosed(Gui::Document* pcDoc) { - if (!d->isClosing && pcDoc) { - try { + try { + if (!d->isClosing && pcDoc) { // Call the closing mechanism from Python. This also checks whether pcDoc is the last open document. Command::doCommand(Command::Doc, "App.closeDocument(\"%s\")", pcDoc->getDocument()->getName()); if (!d->activeDocument && d->documents.size()) { @@ -996,13 +996,20 @@ void Application::onLastWindowClosed(Gui::Document* pcDoc) } } } - catch (const Base::Exception& e) { - e.ReportException(); - } - catch (const Py::Exception&) { - Base::PyException e; - e.ReportException(); - } + } + catch (const Base::Exception& e) { + e.ReportException(); + } + catch (const Py::Exception&) { + Base::PyException e; + e.ReportException(); + } + catch (const std::exception& e) { + Base::Console().Error("Unhandled std::exception caught in Application::onLastWindowClosed.\n" + "The error message is: %s\n", e.what()); + } + catch (...) { + Base::Console().Error("Unhandled unknown exception caught in Application::onLastWindowClosed.\n"); } } diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 99a4ed4917..a48c53a410 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -258,20 +258,38 @@ void PropertyEditor::onItemActivated ( const QModelIndex & index ) setupTransaction(index); } +void PropertyEditor::recomputeDocument(App::Document* doc) +{ + try { + if (doc) { + if (!doc->isTransactionEmpty()) { + // Between opening and committing a transaction a recompute + // could already have been done + if (doc->isTouched()) + doc->recompute(); + } + } + } + // do not re-throw + catch (const Base::Exception& e) { + e.ReportException(); + } + catch (const std::exception& e) { + Base::Console().Error("Unhandled std::exception caught in PropertyEditor::recomputeDocument.\n" + "The error message is: %s\n", e.what()); + } + catch (...) { + Base::Console().Error("Unhandled unknown exception caught in PropertyEditor::recomputeDocument.\n"); + } +} + void PropertyEditor::closeTransaction() { int tid = 0; - if(App::GetApplication().getActiveTransaction(&tid) && tid == transactionID) { + if (App::GetApplication().getActiveTransaction(&tid) && tid == transactionID) { if (autoupdate) { App::Document* doc = App::GetApplication().getActiveDocument(); - if (doc) { - if (!doc->isTransactionEmpty()) { - // Between opening and committing a transaction a recompute - // could already have been done - if (doc->isTouched()) - doc->recompute(); - } - } + recomputeDocument(doc); } App::GetApplication().closeActiveTransaction(); } diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index 288bb4a008..c865b13c24 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -37,6 +37,7 @@ namespace App { class Property; +class Document; } namespace Gui { @@ -110,6 +111,7 @@ private: void updateItemEditor(bool enable, int column, const QModelIndex& parent); void setupTransaction(const QModelIndex &); void closeTransaction(); + void recomputeDocument(App::Document*); private: PropertyItemDelegate *delegate;