Base: improve exception

For better FC and Python exception mapping.
This commit is contained in:
Zheng, Lei
2019-06-21 10:46:43 +08:00
committed by wmayer
parent ea8965cbc2
commit 8f16147a40
9 changed files with 311 additions and 110 deletions

View File

@@ -51,10 +51,21 @@ using namespace Base;
#error "Use Python2.5.x or higher"
#endif
PyException::PyException(const Py::Object &obj) {
_sErrMsg = obj.as_string();
// WARNING: we are assumming that python type object will never be
// destroied, so we don't keep reference here to save book-keeping in
// our copy constructor and desctructor
_exceptionType = (PyObject*)obj.ptr()->ob_type;
_errorType = obj.ptr()->ob_type->tp_name;
}
PyException::PyException(void)
{
PP_Fetch_Error_Text(); /* fetch (and clear) exception */
setPyObject(PP_PyDict_Object);
std::string prefix = PP_last_error_type; /* exception name text */
// prefix += ": ";
std::string error = PP_last_error_info; /* exception data text */
@@ -70,6 +81,16 @@ PyException::PyException(void)
_sErrMsg = error;
_errorType = prefix;
_exceptionType = PP_last_exception_type;
if(PP_last_exception_type) {
// WARNING: we are assumming that python type object will never be
// destroied, so we don't keep reference here to save book-keeping in
// our copy constructor and desctructor
Py_DECREF(PP_last_exception_type);
PP_last_exception_type = 0;
}
_stackTrace = PP_last_error_trace; /* exception traceback text */
@@ -86,31 +107,44 @@ PyException::~PyException() throw()
void PyException::ThrowException(void)
{
PyException myexcp = PyException();
PyException myexcp;
myexcp.ReportException();
myexcp.raiseException();
}
void PyException::raiseException() {
PyGILStateLocker locker;
if (PP_PyDict_Object!=NULL) {
// delete the Python dict upon destruction of edict
Py::Dict edict(PP_PyDict_Object, true);
PP_PyDict_Object = 0;
if (!edict.hasKey("sclassname"))
throw myexcp;
std::string exceptionname = static_cast<std::string>(Py::String(edict.getItem("sclassname")));
if (!Base::ExceptionFactory::Instance().CanProduce(exceptionname.c_str()))
throw myexcp;
std::string exceptionname;
if (_exceptionType == Base::BaseExceptionFreeCADAbort)
edict.setItem("sclassname",
Py::String(typeid(Base::AbortException).name()));
if(_isReported)
edict.setItem("breported", Py::True());
Base::ExceptionFactory::Instance().raiseException(edict.ptr());
}
else
throw myexcp;
if (_exceptionType == Base::BaseExceptionFreeCADAbort) {
Base::AbortException e(_sErrMsg.c_str());
e.setReported(_isReported);
throw e;
}
throw *this;
}
void PyException::ReportException (void) const
{
Base::Console().Error("%s%s: %s\n",
_stackTrace.c_str(), _errorType.c_str(), what());
if (!_isReported) {
_isReported = true;
Base::Console().Error("%s%s: %s\n",
_stackTrace.c_str(), _errorType.c_str(), what());
}
}
// ---------------------------------------------------------