Base: Allow to also throw exception by given Python type

This commit is contained in:
wmayer
2025-03-22 14:44:15 +01:00
committed by Benjamin Nauck
parent 0576c129cd
commit 7358ef9b9f
3 changed files with 37 additions and 8 deletions

View File

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

View File

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

View File

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