Base: Allow to also throw exception by given Python type
This commit is contained in:
@@ -52,11 +52,16 @@ void ExceptionFactory::raiseException(PyObject* pydict) const
|
||||
if (edict.hasKey("sclassname")) {
|
||||
classname = static_cast<std::string>(Py::String(edict.getItem("sclassname")));
|
||||
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
|
||||
pProd = _mpcProducers.find(classname);
|
||||
auto pProd = _mpcProducers.find(classname);
|
||||
if (pProd != _mpcProducers.end()) {
|
||||
static_cast<AbstractExceptionProducer*>(pProd->second)->raiseException(pydict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExceptionFactory::raiseExceptionByType(const PyExceptionData& data) const
|
||||
{
|
||||
for (const auto& it : _mpcProducers) {
|
||||
static_cast<AbstractExceptionProducer*>(it.second)->raiseExceptionByType(data); // NOLINT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "Factory.h"
|
||||
#include <FCGlobal.h>
|
||||
#include <typeinfo>
|
||||
|
||||
// Python stuff
|
||||
@@ -34,6 +35,13 @@ using PyObject = struct _object;
|
||||
namespace Base
|
||||
{
|
||||
|
||||
struct PyExceptionData
|
||||
{
|
||||
PyObject* pyexc {};
|
||||
std::string message;
|
||||
bool reported {};
|
||||
};
|
||||
|
||||
/// Abstract base class of all exception producers
|
||||
class BaseExport AbstractExceptionProducer: public AbstractProducer
|
||||
{
|
||||
@@ -45,6 +53,7 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
virtual void raiseException(PyObject* pydict) const = 0;
|
||||
virtual void raiseExceptionByType(const PyExceptionData&) const = 0;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -57,6 +66,7 @@ public:
|
||||
static void Destruct();
|
||||
|
||||
void raiseException(PyObject* pydict) const;
|
||||
void raiseExceptionByType(const PyExceptionData& data) const;
|
||||
|
||||
private:
|
||||
static ExceptionFactory* _pcSingleton; // NOLINT
|
||||
@@ -72,6 +82,8 @@ class ExceptionProducer: public AbstractExceptionProducer
|
||||
public:
|
||||
ExceptionProducer()
|
||||
{
|
||||
CLASS cls;
|
||||
pyExcType = cls.getPyExceptionType();
|
||||
ExceptionFactory::Instance().AddProducer(typeid(CLASS).name(), this);
|
||||
}
|
||||
|
||||
@@ -82,6 +94,20 @@ public:
|
||||
|
||||
throw cls;
|
||||
}
|
||||
|
||||
void raiseExceptionByType(const PyExceptionData& data) const override
|
||||
{
|
||||
if (pyExcType == data.pyexc) {
|
||||
CLASS cls;
|
||||
cls.setMessage(data.message);
|
||||
cls.setReported(data.reported);
|
||||
|
||||
throw cls;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PyObject* pyExcType {};
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
@@ -114,12 +114,10 @@ void PyException::raiseException()
|
||||
Base::ExceptionFactory::Instance().raiseException(edict.ptr());
|
||||
}
|
||||
|
||||
if (_exceptionType == PyExc_FC_FreeCADAbort) {
|
||||
AbortException exc(getMessage());
|
||||
exc.setReported(getReported());
|
||||
throw exc;
|
||||
}
|
||||
PyExceptionData data {_exceptionType, getMessage(), getReported()};
|
||||
Base::ExceptionFactory::Instance().raiseExceptionByType(data);
|
||||
|
||||
// Fallback
|
||||
throw *this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user