diff --git a/python/modules/IcePy/Logger.cpp b/python/modules/IcePy/Logger.cpp index abf66f2df8d..d5e1f715f67 100644 --- a/python/modules/IcePy/Logger.cpp +++ b/python/modules/IcePy/Logger.cpp @@ -113,7 +113,7 @@ loggerNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) { return nullptr; } - self->logger = 0; + self->logger = nullptr; return self; } diff --git a/python/modules/IcePy/Operation.cpp b/python/modules/IcePy/Operation.cpp index a5459bdaf27..161774cf3e8 100644 --- a/python/modules/IcePy/Operation.cpp +++ b/python/modules/IcePy/Operation.cpp @@ -859,7 +859,7 @@ Operation::marshalResult(Ice::OutputStream& os, PyObject* result) { try { - PyException().raise(); + throwPythonException(); } catch (const Ice::UnknownException& ex) { @@ -879,7 +879,7 @@ Operation::marshalResult(Ice::OutputStream& os, PyObject* result) { try { - PyException().raise(); + throwPythonException(); } catch (const Ice::UnknownException& ex) { diff --git a/python/modules/IcePy/Util.cpp b/python/modules/IcePy/Util.cpp index fce6238b731..5a4e3f4dc06 100644 --- a/python/modules/IcePy/Util.cpp +++ b/python/modules/IcePy/Util.cpp @@ -269,226 +269,132 @@ IcePy::PyObjectHandle::release() return result; } -IcePy::PyException::PyException() -{ - ex = PyErr_GetRaisedException(); - if (ex) - { - PyObject* type = reinterpret_cast(Py_TYPE(ex.get())); - Py_INCREF(type); - _type = type; - _tb = PyException_GetTraceback(ex.get()); - } -} +IcePy::PyException::PyException() { ex = PyErr_GetRaisedException(); } IcePy::PyException::PyException(PyObject* raisedException) { Py_XINCREF(raisedException); ex = raisedException; - PyObject* type = reinterpret_cast(Py_TYPE(raisedException)); - Py_INCREF(type); - _type = type; - _tb = PyException_GetTraceback(raisedException); } -void -IcePy::PyException::raise() +namespace { - assert(ex.get()); - - PyObject* userExceptionType = lookupType("Ice.UserException"); - PyObject* localExceptionType = lookupType("Ice.LocalException"); - - // TODO: create better error messages. - - if (PyObject_IsInstance(ex.get(), userExceptionType)) + string getTypeName(PyObject* ex) { - string tb = getTraceback(); - if (!tb.empty()) - { - throw Ice::UnknownUserException{__FILE__, __LINE__, tb}; - } - else - { - PyObjectHandle name = PyObject_CallMethod(ex.get(), "ice_id", 0); - PyErr_Clear(); - if (!name.get()) - { - throw Ice::UnknownUserException{__FILE__, __LINE__, getTypeName()}; - } - else - { - throw Ice::UnknownUserException{__FILE__, __LINE__, getString(name.get())}; - } - } + PyObject* cls = reinterpret_cast(ex->ob_type); + IcePy::PyObjectHandle name = IcePy::getAttr(cls, "__name__", false); + assert(name.get()); + IcePy::PyObjectHandle mod = IcePy::getAttr(cls, "__module__", false); + assert(mod.get()); + string result = IcePy::getString(mod.get()); + result += "."; + result += IcePy::getString(name.get()); + return result; } - else if (PyObject_IsInstance(ex.get(), localExceptionType)) + string createUnknownExceptionMessage(PyObject* ex) { - raiseLocalException(); - } - else - { - string tb = getTraceback(); - if (!tb.empty()) - { - throw Ice::UnknownException{__FILE__, __LINE__, tb}; - } - else + ostringstream ostr; + ostr << getTypeName(ex); + IcePy::PyObjectHandle exStr = PyObject_Str(ex); + if (exStr.get() && IcePy::checkString(exStr.get())) { - ostringstream ostr; - - ostr << getTypeName(); - - IcePy::PyObjectHandle msg = PyObject_Str(ex.get()); - if (msg.get()) + string message = IcePy::getString(exStr.get()); + if (!message.empty()) { - string s = getString(msg.get()); - if (!s.empty()) - { - ostr << ": " << s; - } + ostr << ": " << message; } - - throw Ice::UnknownException{__FILE__, __LINE__, ostr.str()}; } + return ostr.str(); } } void -IcePy::PyException::checkSystemExit() +IcePy::PyException::raise() { - if (PyObject_IsInstance(ex.get(), PyExc_SystemExit)) + assert(ex.get()); + PyObject* localExceptionType = lookupType("Ice.LocalException"); + if (PyObject_IsInstance(ex.get(), localExceptionType)) { - handleSystemExit(ex.get()); // Does not return. - } -} + string typeName = getTypeName(ex.get()); -void -IcePy::PyException::raiseLocalException() -{ - string typeName = getTypeName(); + PyObject* requestFailedExceptionType = lookupType("Ice.RequestFailedException"); - PyObject* requestFailedExceptionType = lookupType("Ice.RequestFailedException"); + if (PyObject_IsInstance(ex.get(), requestFailedExceptionType)) + { + PyObjectHandle idAttr = getAttr(ex.get(), "id", false); + Ice::Identity id; + if (idAttr.get()) + { + IcePy::getIdentity(idAttr.get(), id); + } + PyObjectHandle facetAttr = getAttr(ex.get(), "facet", false); + string facet = getString(facetAttr.get()); + PyObjectHandle operationAttr = getAttr(ex.get(), "operation", false); + string operation = getString(operationAttr.get()); - if (PyObject_IsInstance(ex.get(), requestFailedExceptionType)) - { - PyObjectHandle idAttr = getAttr(ex.get(), "id", false); - Ice::Identity id; - if (idAttr.get()) + if (typeName == "Ice.ObjectNotExistException") + { + throw Ice::ObjectNotExistException( + __FILE__, + __LINE__, + std::move(id), + std::move(facet), + std::move(operation)); + } + else if (typeName == "Ice.OperationNotExistException") + { + throw Ice::OperationNotExistException( + __FILE__, + __LINE__, + std::move(id), + std::move(facet), + std::move(operation)); + } + else if (typeName == "Ice.FacetNotExistException") + { + throw Ice::FacetNotExistException( + __FILE__, + __LINE__, + std::move(id), + std::move(facet), + std::move(operation)); + } + } + + IcePy::PyObjectHandle exStr = PyObject_Str(ex.get()); + string message; + if (exStr.get() && checkString(exStr.get())) { - IcePy::getIdentity(idAttr.get(), id); + message = getString(exStr.get()); } - PyObjectHandle facetAttr = getAttr(ex.get(), "facet", false); - string facet = getString(facetAttr.get()); - PyObjectHandle operationAttr = getAttr(ex.get(), "operation", false); - string operation = getString(operationAttr.get()); - if (typeName == "Ice.ObjectNotExistException") + if (typeName == "Ice.UnknownLocalException") { - throw Ice::ObjectNotExistException( - __FILE__, - __LINE__, - std::move(id), - std::move(facet), - std::move(operation)); + throw Ice::UnknownLocalException{__FILE__, __LINE__, std::move(message)}; } - else if (typeName == "Ice.OperationNotExistException") + else if (typeName == "Ice.UnknownUserException") { - throw Ice::OperationNotExistException( - __FILE__, - __LINE__, - std::move(id), - std::move(facet), - std::move(operation)); + throw Ice::UnknownUserException{__FILE__, __LINE__, std::move(message)}; } - else if (typeName == "Ice.FacetNotExistException") + else if (typeName == "Ice.UnknownException") { - throw Ice::FacetNotExistException( - __FILE__, - __LINE__, - std::move(id), - std::move(facet), - std::move(operation)); + throw Ice::UnknownException{__FILE__, __LINE__, std::move(message)}; } - } - - IcePy::PyObjectHandle exStr = PyObject_Str(ex.get()); - string message; - if (exStr.get() && checkString(exStr.get())) - { - message = getString(exStr.get()); - } - - if (typeName == "Ice.UnknownLocalException") - { - throw Ice::UnknownLocalException{__FILE__, __LINE__, std::move(message)}; - } - else if (typeName == "Ice.UnknownUserException") - { - throw Ice::UnknownUserException{__FILE__, __LINE__, std::move(message)}; - } - else if (typeName == "Ice.UnknownException") - { - throw Ice::UnknownException{__FILE__, __LINE__, std::move(message)}; - } - - string tb = getTraceback(); - if (!tb.empty()) - { - throw Ice::UnknownLocalException{__FILE__, __LINE__, tb}; + throw Ice::UnknownLocalException{__FILE__, __LINE__, createUnknownExceptionMessage(ex.get())}; } else { - throw Ice::UnknownLocalException{__FILE__, __LINE__, typeName}; + throw Ice::UnknownException{__FILE__, __LINE__, createUnknownExceptionMessage(ex.get())}; } } -string -IcePy::PyException::getTraceback() +void +IcePy::PyException::checkSystemExit() { - if (!_tb.get()) - { - return string(); - } - - // - // We need the equivalent of the following Python code: - // - // import traceback - // list = traceback.format_exception(type, ex, tb) - // - PyObjectHandle str = createString("traceback"); - PyObjectHandle mod = PyImport_Import(str.get()); - assert(mod.get()); // Unable to import traceback module - Python installation error? - PyObject* func = PyDict_GetItemString(PyModule_GetDict(mod.get()), "format_exception"); - assert(func); // traceback.format_exception must be present. - PyObjectHandle args = Py_BuildValue("(OOO)", _type.get(), ex.get(), _tb.get()); - assert(args.get()); - PyObjectHandle list = PyObject_CallObject(func, args.get()); - assert(list.get()); - - string result; - for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list.get()); ++i) + if (PyObject_IsInstance(ex.get(), PyExc_SystemExit)) { - string s = getString(PyList_GetItem(list.get(), i)); - result += s; + handleSystemExit(ex.get()); // Does not return. } - - return result; -} - -string -IcePy::PyException::getTypeName() -{ - PyObject* cls = reinterpret_cast(ex.get()->ob_type); - PyObjectHandle name = getAttr(cls, "__name__", false); - assert(name.get()); - PyObjectHandle mod = getAttr(cls, "__module__", false); - assert(mod.get()); - string result = getString(mod.get()); - result += "."; - result += getString(name.get()); - return result; } PyObject* @@ -767,7 +673,6 @@ IcePy::convertException(std::exception_ptr exPtr) IcePy::createString(ex.kindOfObject()), IcePy::createString(ex.id()), IcePy::createString(ex.what())}; - return createPythonException(ex.ice_id(), std::move(args)); } catch (const Ice::NotRegisteredException& ex) @@ -776,7 +681,6 @@ IcePy::convertException(std::exception_ptr exPtr) IcePy::createString(ex.kindOfObject()), IcePy::createString(ex.id()), IcePy::createString(ex.what())}; - return createPythonException(ex.ice_id(), std::move(args)); } catch (const Ice::ConnectionAbortedException& ex) @@ -796,7 +700,6 @@ IcePy::convertException(std::exception_ptr exPtr) IcePy::createString(ex.facet()), IcePy::createString(ex.operation()), IcePy::createString(ex.what())}; - return createPythonException(ex.ice_id(), std::move(args)); } // Then all other exceptions. diff --git a/python/modules/IcePy/Util.h b/python/modules/IcePy/Util.h index 60fd7ead059..e47b7f778ec 100644 --- a/python/modules/IcePy/Util.h +++ b/python/modules/IcePy/Util.h @@ -87,7 +87,7 @@ namespace IcePy PyException(PyObject*); // - // Convert the Python exception to its C++ equivalent. + // Converts the Python exception into one of the 6 special Ice local exceptions. // void raise(); @@ -97,14 +97,6 @@ namespace IcePy void checkSystemExit(); PyObjectHandle ex; - - private: - void raiseLocalException(); - std::string getTraceback(); - std::string getTypeName(); - - PyObjectHandle _type; - PyObjectHandle _tb; }; //