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.
This commit is contained in:
Zheng, Lei
2018-08-22 16:51:48 +08:00
committed by wmayer
parent 561be08211
commit 69efa47374
3 changed files with 32 additions and 4 deletions

View File

@@ -32,7 +32,9 @@
#include <set>
#include <cstring>
#include <cstdio>
#include <exception>
#include "Exception.h"
#include "Console.h"
namespace Base
{
@@ -172,7 +174,19 @@ public:
void Notify(_MessageType rcReason)
{
for(typename std::set<Observer<_MessageType> * >::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

View File

@@ -49,7 +49,7 @@
#include <Gui/SelectionObjectPy.h>
#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");
}
}

View File

@@ -141,6 +141,7 @@ public:
private:
virtual void onSelectionChanged(const SelectionChanges& msg) = 0;
void _onSelectionChanged(const SelectionChanges& msg);
private:
typedef boost::signals::connection Connection;