Enable exceptions to save/restore information in a python dictionary and enable throwing exception from dictionary information
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Console.h"
|
||||
@@ -97,6 +98,47 @@ void Exception::ReportException (void) const
|
||||
Console().Error("Exception (%s): %s \n",Console().Time(),str.c_str());
|
||||
}
|
||||
|
||||
PyObject * Exception::getPyDict() const
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(*this).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(this->getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(this->getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(this->getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(this->getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(this->what()));
|
||||
|
||||
return edict;
|
||||
}
|
||||
|
||||
void Exception::setPyDict( PyObject * pydict)
|
||||
{
|
||||
if(pydict!=NULL) {
|
||||
PyObject *pystring;
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sfile");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_file = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sfunction");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_function = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sErrMsg");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_sErrMsg = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"iline");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_line = PyInt_AsLong(pystring);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
|
||||
@@ -241,6 +283,52 @@ void FileException::ReportException (void) const
|
||||
Console().Error("Exception (%s): %s \n",Console().Time(),str.c_str());
|
||||
}
|
||||
|
||||
PyObject * FileException::getPyDict() const
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(*this).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(this->getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(this->getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(this->getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(this->getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(this->what()));
|
||||
PyDict_SetItemString(edict, "filename", PyString_FromString(this->file.fileName().c_str()));
|
||||
|
||||
return edict;
|
||||
}
|
||||
|
||||
void FileException::setPyDict( PyObject * pydict)
|
||||
{
|
||||
if(pydict!=NULL) {
|
||||
PyObject *pystring;
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sfile");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_file = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sfunction");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_function = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"sErrMsg");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_sErrMsg = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"iline");
|
||||
|
||||
if(pystring!=NULL)
|
||||
_line = PyInt_AsLong(pystring);
|
||||
|
||||
pystring = PyDict_GetItemString(pydict,"filename");
|
||||
|
||||
if(pystring!=NULL)
|
||||
file = FileInfo(PyString_AsString(pystring));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <signal.h>
|
||||
#include <Python.h>
|
||||
#include "FileInfo.h"
|
||||
#include "BaseClass.h"
|
||||
|
||||
@@ -83,6 +84,10 @@ public:
|
||||
/// setter methods for including debug information
|
||||
/// intended to use via macro for autofilling of debugging information
|
||||
inline void setDebugInformation(const std::string & file, const int line, const std::string & function);
|
||||
/// returns a Python dictionary containing the exception data
|
||||
virtual PyObject * getPyDict() const;
|
||||
/// returns sets the exception data from a Python dictionary
|
||||
virtual void setPyDict( PyObject * pydict);
|
||||
|
||||
protected:
|
||||
public: // FIXME: Remove the public keyword
|
||||
@@ -187,6 +192,10 @@ public:
|
||||
virtual void ReportException (void) const;
|
||||
/// Get file name for use with tranlatable message
|
||||
std::string getFileName() const;
|
||||
/// returns a Python dictionary containing the exception data
|
||||
virtual PyObject * getPyDict() const;
|
||||
/// returns sets the exception data from a Python dictionary
|
||||
virtual void setPyDict( PyObject * pydict);
|
||||
protected:
|
||||
FileInfo file;
|
||||
// necesary for what() legacy behaviour as it returns a buffer that can not be of a temporary object to be destroyed at end of what()
|
||||
|
||||
@@ -42,15 +42,22 @@ void ExceptionFactory::Destruct (void)
|
||||
_pcSingleton = 0;
|
||||
}
|
||||
|
||||
void ExceptionFactory::raiseException (const ExceptionInfo& info) const
|
||||
void ExceptionFactory::raiseException (PyObject * pydict) const
|
||||
{
|
||||
if(this->CanProduce(info.exceptionname.c_str())) {
|
||||
std::string classname;
|
||||
|
||||
PyObject *pystring;
|
||||
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
pystring = PyDict_GetItemString(pydict,"sclassname");
|
||||
|
||||
pProd = _mpcProducers.find(info.exceptionname.c_str());
|
||||
if (pProd != _mpcProducers.end())
|
||||
static_cast<AbstractExceptionProducer *>(pProd->second)->raiseException(info);
|
||||
if(pystring!=NULL) {
|
||||
classname = std::string(PyString_AsString(pystring));
|
||||
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
|
||||
pProd = _mpcProducers.find(classname.c_str());
|
||||
if (pProd != _mpcProducers.end())
|
||||
static_cast<AbstractExceptionProducer *>(pProd->second)->raiseException(pydict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,20 +25,13 @@
|
||||
#define BASE_EXCEPTIONFACTORY_H
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "Factory.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
struct ExceptionInfo {
|
||||
std::string exceptionname;
|
||||
std::string function;
|
||||
std::string message;
|
||||
std::string file;
|
||||
unsigned int line;
|
||||
};
|
||||
|
||||
/// Abstract base class of all exception producers
|
||||
class BaseExport AbstractExceptionProducer : public AbstractProducer
|
||||
{
|
||||
@@ -49,7 +42,7 @@ public:
|
||||
void* Produce () const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual void raiseException(const ExceptionInfo& info) const = 0;
|
||||
virtual void raiseException(PyObject * pydict) const = 0;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -61,7 +54,7 @@ public:
|
||||
static ExceptionFactory& Instance(void);
|
||||
static void Destruct (void);
|
||||
|
||||
void raiseException(const ExceptionInfo& info) const;
|
||||
void raiseException(PyObject * pydict) const;
|
||||
|
||||
private:
|
||||
static ExceptionFactory* _pcSingleton;
|
||||
@@ -83,13 +76,11 @@ public:
|
||||
|
||||
virtual ~ExceptionProducer (){}
|
||||
|
||||
void raiseException(const ExceptionInfo& info) const
|
||||
void raiseException(PyObject * pydict) const
|
||||
{
|
||||
CLASS c;
|
||||
|
||||
c.setMessage(info.message);
|
||||
|
||||
c.setDebugInformation(info.file, info.line, info.function);
|
||||
c.setPyDict(pydict);
|
||||
|
||||
throw c;
|
||||
}
|
||||
|
||||
@@ -90,41 +90,19 @@ void PyException::ThrowException(void)
|
||||
|
||||
if(PP_PyDict_Object!=NULL) {
|
||||
|
||||
Base::ExceptionInfo info;
|
||||
|
||||
PyObject *pystring;
|
||||
|
||||
pystring = PyDict_GetItemString(PP_PyDict_Object,"sclassname");
|
||||
|
||||
|
||||
if(pystring==NULL)
|
||||
throw myexcp;
|
||||
|
||||
info.exceptionname = std::string(PyString_AsString(pystring));
|
||||
|
||||
if(!Base::ExceptionFactory::Instance().CanProduce(info.exceptionname.c_str()))
|
||||
|
||||
std::string exceptionname = std::string(PyString_AsString(pystring));
|
||||
|
||||
if(!Base::ExceptionFactory::Instance().CanProduce(exceptionname.c_str()))
|
||||
throw myexcp;
|
||||
|
||||
pystring = PyDict_GetItemString(PP_PyDict_Object,"sfile");
|
||||
|
||||
if(pystring!=NULL)
|
||||
info.file = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(PP_PyDict_Object,"sfunction");
|
||||
|
||||
if(pystring!=NULL)
|
||||
info.function = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(PP_PyDict_Object,"sErrMsg");
|
||||
|
||||
if(pystring!=NULL)
|
||||
info.message = std::string(PyString_AsString(pystring));
|
||||
|
||||
pystring = PyDict_GetItemString(PP_PyDict_Object,"iline");
|
||||
|
||||
if(pystring!=NULL)
|
||||
info.line = PyInt_AsLong(pystring);
|
||||
|
||||
Base::ExceptionFactory::Instance().raiseException(info);
|
||||
|
||||
Base::ExceptionFactory::Instance().raiseException(PP_PyDict_Object);
|
||||
}
|
||||
else
|
||||
throw myexcp;
|
||||
|
||||
@@ -494,14 +494,7 @@ PyObject * @self.export.Name@::staticCallback_@i.Name@ (PyObject *self, PyObject
|
||||
}
|
||||
catch(const Base::Exception& e) // catch the FreeCAD exceptions
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(e).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(e.getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(e.getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(e.getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(e.getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(e.what()));
|
||||
PyObject *edict = e.getPyDict();
|
||||
|
||||
e.ReportException();
|
||||
PyErr_SetObject(Base::BaseExceptionFreeCADError, edict);
|
||||
@@ -691,14 +684,7 @@ PyObject *@self.export.Name@::_getattr(char *attr) // __getattr__ function: n
|
||||
#ifndef DONT_CATCH_CXX_EXCEPTIONS
|
||||
catch(const Base::Exception& e) // catch the FreeCAD exceptions
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(e).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(e.getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(e.getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(e.getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(e.getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(e.what()));
|
||||
PyObject *edict = e.getPyDict();
|
||||
|
||||
e.ReportException();
|
||||
PyErr_SetObject(Base::BaseExceptionFreeCADError, edict);
|
||||
@@ -728,14 +714,7 @@ PyObject *@self.export.Name@::_getattr(char *attr) // __getattr__ function: n
|
||||
#else // DONT_CATCH_CXX_EXCEPTIONS
|
||||
catch(const Base::Exception& e) // catch the FreeCAD exceptions
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(e).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(e.getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(e.getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(e.getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(e.getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(e.what()));
|
||||
PyObject *edict = e.getPyDict();
|
||||
|
||||
e.ReportException();
|
||||
PyErr_SetObject(Base::BaseExceptionFreeCADError, edict);
|
||||
@@ -778,14 +757,7 @@ int @self.export.Name@::_setattr(char *attr, PyObject *value) // __setattr__ fun
|
||||
#ifndef DONT_CATCH_CXX_EXCEPTIONS
|
||||
catch(const Base::Exception& e) // catch the FreeCAD exceptions
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(e).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(e.getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(e.getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(e.getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(e.getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(e.what()));
|
||||
PyObject *edict = e.getPyDict();
|
||||
|
||||
e.ReportException();
|
||||
PyErr_SetObject(Base::BaseExceptionFreeCADError, edict);
|
||||
@@ -816,14 +788,7 @@ int @self.export.Name@::_setattr(char *attr, PyObject *value) // __setattr__ fun
|
||||
#else // DONT_CATCH_CXX_EXCEPTIONS
|
||||
catch(const Base::Exception& e) // catch the FreeCAD exceptions
|
||||
{
|
||||
PyObject *edict = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(edict, "sclassname", PyString_FromString(typeid(e).name()));
|
||||
PyDict_SetItemString(edict, "sErrMsg", PyString_FromString(e.getMessage().c_str()));
|
||||
PyDict_SetItemString(edict, "sfile", PyString_FromString(e.getFile().c_str()));
|
||||
PyDict_SetItemString(edict, "iline", PyInt_FromLong(e.getLine()));
|
||||
PyDict_SetItemString(edict, "sfunction", PyString_FromString(e.getFunction().c_str()));
|
||||
PyDict_SetItemString(edict, "swhat", PyString_FromString(e.what()));
|
||||
PyObject *edict = e.getPyDict();
|
||||
|
||||
e.ReportException();
|
||||
PyErr_SetObject(Base::BaseExceptionFreeCADError, edict);
|
||||
|
||||
Reference in New Issue
Block a user