From 69efa473745279222ae4010020e8097dc8d8411a Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Wed, 22 Aug 2018 16:51:48 +0800 Subject: [PATCH] Selection: handle exception in observer callback Selection callback are sometimes called while traversing Coin node tree. If any unhandled exception is thrown while traversing the tree, FC 3D rendering will become unstable and non-usable thereafter. --- src/Base/Observer.h | 18 ++++++++++++++++-- src/Gui/Selection.cpp | 17 +++++++++++++++-- src/Gui/Selection.h | 1 + 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Base/Observer.h b/src/Base/Observer.h index 545e8f78af..dfd1227d77 100644 --- a/src/Base/Observer.h +++ b/src/Base/Observer.h @@ -32,7 +32,9 @@ #include #include #include - +#include +#include "Exception.h" +#include "Console.h" namespace Base { @@ -172,7 +174,19 @@ public: void Notify(_MessageType rcReason) { for(typename std::set * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();++Iter) - (*Iter)->OnChange(*this,rcReason); // send OnChange-signal + { + try { + (*Iter)->OnChange(*this,rcReason); // send OnChange-signal + } catch (Base::Exception &e) { + Base::Console().Error("Unhandled Base::Exception caught when notifying observer.\n" + "The error message is: %s\n", e.what()); + } catch (std::exception &e) { + Base::Console().Error("Unhandled std::exception caught when notifying observer\n" + "The error message is: %s\n", e.what()); + } catch (...) { + Base::Console().Error("Unhandled unknown exception caught in when notifying observer.\n"); + } + } } /** Get an Observer by name diff --git a/src/Gui/Selection.cpp b/src/Gui/Selection.cpp index 6087cc9dbb..b544da3334 100644 --- a/src/Gui/Selection.cpp +++ b/src/Gui/Selection.cpp @@ -49,7 +49,7 @@ #include #include "MainWindow.h" - +FC_LOG_LEVEL_INIT("Selection",false,true,true) using namespace Gui; using namespace std; @@ -83,7 +83,20 @@ void SelectionObserver::attachSelection() { if (!connectSelection.connected()) { connectSelection = Selection().signalSelectionChanged.connect(boost::bind - (&SelectionObserver::onSelectionChanged, this, _1)); + (&SelectionObserver::_onSelectionChanged, this, _1)); + } +} + +void SelectionObserver::_onSelectionChanged(const SelectionChanges& msg) { + try { + onSelectionChanged(msg); + } catch (Base::Exception &e) { + e.ReportException(); + FC_ERR("Unhandled Base::Exception caught in selection observer: "); + } catch (std::exception &e) { + FC_ERR("Unhandled std::exception caught in selection observer: " << e.what()); + } catch (...) { + FC_ERR("Unhandled unknown exception caught in selection observer"); } } diff --git a/src/Gui/Selection.h b/src/Gui/Selection.h index 6696a1edeb..02d4925e5a 100644 --- a/src/Gui/Selection.h +++ b/src/Gui/Selection.h @@ -141,6 +141,7 @@ public: private: virtual void onSelectionChanged(const SelectionChanges& msg) = 0; + void _onSelectionChanged(const SelectionChanges& msg); private: typedef boost::signals::connection Connection;