summaryrefslogtreecommitdiff
path: root/py/modules/IcePy/Util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'py/modules/IcePy/Util.cpp')
-rw-r--r--py/modules/IcePy/Util.cpp324
1 files changed, 324 insertions, 0 deletions
diff --git a/py/modules/IcePy/Util.cpp b/py/modules/IcePy/Util.cpp
index 355a07ce6b4..990cbb4b569 100644
--- a/py/modules/IcePy/Util.cpp
+++ b/py/modules/IcePy/Util.cpp
@@ -8,6 +8,8 @@
// **********************************************************************
#include <Util.h>
+#include <Identity.h>
+#include <Ice/LocalException.h>
using namespace std;
@@ -341,3 +343,325 @@ IcePy::lookupType(const string& typeName)
return PyDict_GetItemString(dict, const_cast<char*>(name.c_str()));
}
+
+PyObject*
+IcePy::getPythonException(bool clear)
+{
+ PyObject* t;
+ PyObject* val;
+ PyObject* tb;
+
+ PyErr_Fetch(&t, &val, &tb); // PyErr_Fetch clears the exception.
+ PyErr_NormalizeException(&t, &val, &tb);
+
+ if(clear)
+ {
+ Py_XDECREF(t);
+ Py_XDECREF(tb);
+ }
+ else
+ {
+ Py_XINCREF(val);
+ PyErr_Restore(t, val, tb);
+ }
+
+ return val; // New reference.
+}
+
+PyObject*
+IcePy::createExceptionInstance(PyObject* type)
+{
+ assert(PyClass_Check(type));
+ IcePy::PyObjectHandle args = PyTuple_New(0);
+ if(args.get() == NULL)
+ {
+ return NULL;
+ }
+ return PyEval_CallObject(type, args.get());
+}
+
+void
+IcePy::setPythonException(const Ice::Exception& ex)
+{
+ PyObjectHandle p;
+ PyObject* type;
+
+ ostringstream ostr;
+ ostr << ex;
+ string str = ostr.str();
+
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::AlreadyRegisteredException& e)
+ {
+ type = lookupType("Ice.AlreadyRegisteredException");
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s;
+ s = PyString_FromString(const_cast<char*>(e.kindOfObject.c_str()));
+ PyObject_SetAttrString(p.get(), "kindOfObject", s.get());
+ s = PyString_FromString(const_cast<char*>(e.id.c_str()));
+ PyObject_SetAttrString(p.get(), "id", s.get());
+ }
+ }
+ catch(const Ice::NotRegisteredException& e)
+ {
+ type = lookupType("Ice.NotRegisteredException");
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s;
+ s = PyString_FromString(const_cast<char*>(e.kindOfObject.c_str()));
+ PyObject_SetAttrString(p.get(), "kindOfObject", s.get());
+ s = PyString_FromString(const_cast<char*>(e.id.c_str()));
+ PyObject_SetAttrString(p.get(), "id", s.get());
+ }
+ }
+ catch(const Ice::RequestFailedException& e)
+ {
+ type = lookupType(scopedToName(e.ice_name()));
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle m;
+ m = createIdentity(e.id);
+ PyObject_SetAttrString(p.get(), "id", m.get());
+ m = PyString_FromString(const_cast<char*>(e.facet.c_str()));
+ PyObject_SetAttrString(p.get(), "facet", m.get());
+ m = PyString_FromString(const_cast<char*>(e.operation.c_str()));
+ PyObject_SetAttrString(p.get(), "operation", m.get());
+ }
+ }
+ catch(const Ice::UnknownException& e)
+ {
+ type = lookupType(scopedToName(e.ice_name()));
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s = PyString_FromString(const_cast<char*>(e.unknown.c_str()));
+ PyObject_SetAttrString(p.get(), "unknown", s.get());
+ }
+ }
+ catch(const Ice::NoObjectFactoryException& e)
+ {
+ type = lookupType(scopedToName(e.ice_name()));
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle m;
+ m = PyString_FromString(const_cast<char*>(e.type.c_str()));
+ PyObject_SetAttrString(p.get(), "type", m.get());
+ }
+ }
+ catch(const Ice::LocalException& e)
+ {
+ type = lookupType(scopedToName(e.ice_name()));
+ if(type != NULL)
+ {
+ p = createExceptionInstance(type);
+ }
+ else
+ {
+ type = lookupType("Ice.UnknownLocalException");
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s = PyString_FromString(const_cast<char*>(str.c_str()));
+ PyObject_SetAttrString(p.get(), "unknown", s.get());
+ }
+ }
+ }
+ catch(const Ice::UserException& e)
+ {
+ type = lookupType("Ice.UnknownUserException");
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s = PyString_FromString(const_cast<char*>(str.c_str()));
+ PyObject_SetAttrString(p.get(), "unknown", s.get());
+ }
+ }
+ catch(const Ice::Exception& e)
+ {
+ type = lookupType("Ice.UnknownException");
+ assert(type != NULL);
+ p = createExceptionInstance(type);
+ if(p.get() != NULL)
+ {
+ PyObjectHandle s = PyString_FromString(const_cast<char*>(str.c_str()));
+ PyObject_SetAttrString(p.get(), "unknown", s.get());
+ }
+ }
+
+ if(p.get() != NULL)
+ {
+ Py_INCREF(type);
+ PyErr_Restore(type, p.release(), NULL);
+ }
+}
+
+static void
+throwLocalException(PyObject* ex)
+{
+ string typeName = ex->ob_type->tp_name;
+
+ try
+ {
+ if(typeName == "Ice.ObjectNotExistException")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(typeName == "Ice.OperationNotExistException")
+ {
+ throw Ice::OperationNotExistException(__FILE__, __LINE__);
+ }
+ else if(typeName == "Ice.FacetNotExistException")
+ {
+ throw Ice::FacetNotExistException(__FILE__, __LINE__);
+ }
+ else if(typeName == "Ice.RequestFailedException")
+ {
+ throw Ice::RequestFailedException(__FILE__, __LINE__);
+ }
+ }
+ catch(Ice::RequestFailedException& e)
+ {
+ IcePy::PyObjectHandle member;
+ member = PyObject_GetAttrString(ex, "id");
+ if(member.get() != NULL && IcePy::checkIdentity(member.get()))
+ {
+ IcePy::getIdentity(member.get(), e.id);
+ }
+ member = PyObject_GetAttrString(ex, "facet");
+ if(member.get() != NULL && PyString_Check(member.get()))
+ {
+ e.facet = PyString_AS_STRING(member.get());
+ }
+ member = PyObject_GetAttrString(ex, "operation");
+ if(member.get() != NULL && PyString_Check(member.get()))
+ {
+ e.operation = PyString_AS_STRING(member.get());
+ }
+ throw e;
+ }
+
+ try
+ {
+ if(typeName == "Ice.UnknownLocalException")
+ {
+ throw Ice::UnknownLocalException(__FILE__, __LINE__);
+ }
+ else if(typeName == "Ice.UnknownUserException")
+ {
+ throw Ice::UnknownUserException(__FILE__, __LINE__);
+ }
+ else if(typeName == "Ice.UnknownException")
+ {
+ throw Ice::UnknownException(__FILE__, __LINE__);
+ }
+ }
+ catch(Ice::UnknownException& e)
+ {
+ IcePy::PyObjectHandle member;
+ member = PyObject_GetAttrString(ex, "unknown");
+ if(member.get() != NULL && PyString_Check(member.get()))
+ {
+ e.unknown = PyString_AS_STRING(member.get());
+ }
+ throw e;
+ }
+
+ Ice::UnknownLocalException e(__FILE__, __LINE__);
+ e.unknown = typeName;
+ throw e;
+}
+
+void
+IcePy::throwPythonException(PyObject* ex)
+{
+ PyObjectHandle h;
+ if(ex == NULL)
+ {
+ h = getPythonException();
+ ex = h.get();
+ }
+
+ PyObject* userExceptionType = lookupType("Ice.UserException");
+ PyObject* localExceptionType = lookupType("Ice.LocalException");
+
+ if(PyObject_IsInstance(ex, userExceptionType))
+ {
+ PyObjectHandle id = PyObject_CallMethod(ex, "ice_id", NULL);
+ PyErr_Clear();
+ Ice::UnknownUserException e(__FILE__, __LINE__);
+ if(id.get() == NULL)
+ {
+ e.unknown = ex->ob_type->tp_name;
+ }
+ else
+ {
+ e.unknown = PyString_AS_STRING(id.get());
+ }
+ throw e;
+ }
+ else if(PyObject_IsInstance(ex, localExceptionType))
+ {
+ throwLocalException(ex);
+ }
+ else
+ {
+ PyObjectHandle str = PyObject_Str(ex);
+ assert(str.get() != NULL);
+ assert(PyString_Check(str.get()));
+
+ Ice::UnknownException e(__FILE__, __LINE__);
+ e.unknown = PyString_AS_STRING(str.get());
+ throw e;
+ }
+}
+
+void
+IcePy::handleSystemExit()
+{
+ PyObjectHandle ex = getPythonException();
+ assert(ex.get() != NULL);
+
+ //
+ // This code is similar to handle_system_exit in pythonrun.c.
+ //
+ PyObjectHandle code;
+ if(PyInstance_Check(ex.get()))
+ {
+ code = PyObject_GetAttrString(ex.get(), "code");
+ }
+ else
+ {
+ code = ex;
+ }
+
+ int status;
+ if(PyInt_Check(code.get()))
+ {
+ status = static_cast<int>(PyInt_AsLong(code.get()));
+ }
+ else
+ {
+ PyObject_Print(code.get(), stderr, Py_PRINT_RAW);
+ PySys_WriteStderr("\n");
+ status = 1;
+ }
+
+ code = 0;
+ ex = 0;
+ Py_Exit(status);
+}