Reputation: 224129
I have some C++ code that runs Python 3 code using Boost.Python. If any exception in Python occurs, it is caught and a C++ exception thrown. I want to pass some minimal error information to the C++ exception.
What I currently have is this:
try {
// execute python code via Boost.Python
} catch(boost::python::error_already_set&) {
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if(pvalue) {
// ???
}
}
There are many helpful answers here at SO, but they all seem to apply to Python 2, and their solutions do not work anymore. I have tried a few things like PyBytes_AsString
, PyUnicode_AsUTF8
, but all I get back are null pointers.
How do I go about extracting something meaningful from pvalue
? For starters, the type name of the exception raised would already be quite helpful. If there was a string passed to the exception, getting that would be most helpful.
Upvotes: 0
Views: 1246
Reputation: 224129
Of course, I found a solution myself immediately after I had formulated and posted this question.
This code finally does the trick and provides nice messages:
try {
// execute python code via Boost.Python
} catch(boost::python::error_already_set&) {
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if(pvalue) {
PyObject *pstr = PyObject_Str(pvalue);
if(pstr) {
const char* err_msg = PyUnicode_AsUTF8(pstr);
if(pstr)
// use err_msg
}
PyErr_Restore(ptype, pvalue, ptraceback);
}
}
I'd be glad for any feedback, though. I know little of Python and less of its C API.
Upvotes: 4