Exemplo n.º 1
0
std::wstring PyError::get_python_error_description()
{
	std::wstring ret = L"Unfetchable Python error";

	PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL;
    PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
    
	if(type_ptr != NULL)
	{
		py::handle<> h_type(type_ptr);
		py::str type_pstr(h_type);
		py::extract<std::wstring> e_type_pstr(type_pstr);
		if(e_type_pstr.check())
			ret = e_type_pstr();
		else
			ret = L"Unknown exception type";
	}

	if(value_ptr != NULL)
	{
		py::handle<> h_val(value_ptr);
		py::str a(h_val);
		py::extract<std::wstring> returned(a);
		if(returned.check())
			ret +=  L": " + returned();
		else
			ret += L": Unparseable Python error: ";
	}

	if(traceback_ptr != NULL)
	{
		py::handle<> h_tb(traceback_ptr);
		py::object tb(py::import("traceback"));
		py::object fmt_tb(tb.attr("format_tb"));
		py::object tb_list(fmt_tb(h_tb));
		py::object tb_str(py::str("\n").join(tb_list));
		py::extract<std::wstring> returned(tb_str);
		if(returned.check())
			ret += L": " + returned();
		else
			ret += L": Unparseable Python traceback";
	}

	return ret;
}
static std::string parse_python_exception()
{
    PyObject * type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL;
    // Fetch the exception info from the Python C API
    PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
    // Fallback error
    std::string ret("Unfetchable Python error");

    // If the fetch got a type pointer, parse the type into the exception string
    if (type_ptr != NULL)
    {
        handle<> h_type(type_ptr);
        str type_pstr(h_type);
        // Extract the string from the boost::python object
        extract<std::string> e_type_pstr(type_pstr);

        // If a valid string extraction is available, use it
        // otherwise use fallback
        if (e_type_pstr.check())
        {
            ret = e_type_pstr();
        }

        else
        {
            ret = "Unknown exception type";
        }
    }

    // Do the same for the exception value (the stringification of the exception)
    if (value_ptr != NULL)
    {
        handle<> h_val(value_ptr);
        str a(h_val);
        extract<std::string> returned(a);

        if (returned.check())
        {
            ret += ": " + returned();
        }

        else
        {
            ret += std::string(": Unparseable Python error: ");
        }
    }

    // Parse lines from the traceback using the Python traceback module
    if (traceback_ptr != NULL)
    {
        handle<> h_tb(traceback_ptr);
        // Load the traceback module and the format_tb function
        object tb(import("traceback"));
        object fmt_tb(tb.attr("format_tb"));
        // Call format_tb to get a list of traceback strings
        object tb_list(fmt_tb(h_tb));
        // Join the traceback strings into a single string
        object tb_str(str("\n").join(tb_list));
        // Extract the string, check the extraction, and fallback in necessary
        extract<std::string> returned(tb_str);

        if (returned.check())
        {
            ret += ": " + returned();
        }

        else
        {
            ret += std::string(": Unparseable Python traceback");
        }
    }

    return ret;
}