How to get Python exception text How to get Python exception text python python

How to get Python exception text


Well, I found out how to do it.

Without boost (only error message, because code to extract info from traceback is too heavy to post it here):

PyObject *ptype, *pvalue, *ptraceback;PyErr_Fetch(&ptype, &pvalue, &ptraceback);//pvalue contains error message//ptraceback contains stack snapshot and many other information//(see python traceback structure)//Get error messagechar *pStrErrorMessage = PyString_AsString(pvalue);

And BOOST version

try{//some code that throws an error}catch(error_already_set &){    PyObject *ptype, *pvalue, *ptraceback;    PyErr_Fetch(&ptype, &pvalue, &ptraceback);    handle<> hType(ptype);    object extype(hType);    handle<> hTraceback(ptraceback);    object traceback(hTraceback);    //Extract error message    string strErrorMessage = extract<string>(pvalue);    //Extract line number (top entry of call stack)    // if you want to extract another levels of call stack    // also process traceback.attr("tb_next") recurently    long lineno = extract<long> (traceback.attr("tb_lineno"));    string filename = extract<string>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));    string funcname = extract<string>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));... //cleanup here


This is the most robust method I've been able to come up so far:

    try {        ...    }    catch (bp::error_already_set) {        if (PyErr_Occurred()) {            msg = handle_pyerror();         }        py_exception = true;        bp::handle_exception();        PyErr_Clear();    }    if (py_exception)     ....// decode a Python exception into a stringstd::string handle_pyerror(){    using namespace boost::python;    using namespace boost;    PyObject *exc,*val,*tb;    object formatted_list, formatted;    PyErr_Fetch(&exc,&val,&tb);    handle<> hexc(exc),hval(allow_null(val)),htb(allow_null(tb));     object traceback(import("traceback"));    if (!tb) {        object format_exception_only(traceback.attr("format_exception_only"));        formatted_list = format_exception_only(hexc,hval);    } else {        object format_exception(traceback.attr("format_exception"));        formatted_list = format_exception(hexc,hval,htb);    }    formatted = str("\n").join(formatted_list);    return extract<std::string>(formatted);}


In the Python C API, PyObject_Str returns a new reference to a Python string object with the string form of the Python object you're passing as the argument -- just like str(o) in Python code. Note that the exception object does not have "information like line number" -- that's in the traceback object (you can use PyErr_Fetch to get both the exception object and the traceback object). Don't know what (if anything) Boost provides to make these specific C API functions easier to use, but, worst case, you could always resort to these functions as they are offered in the C API itself.