diff options
| author | ZipCPU <dgisselq@ieee.org> | 2018-06-06 07:55:18 -0400 |
|---|---|---|
| committer | ZipCPU <dgisselq@ieee.org> | 2018-06-06 07:55:18 -0400 |
| commit | d0ee08aeb12a8fb7237b31083666d9b165f13f69 (patch) | |
| tree | e09d84b0389462f2c1959ce59438d88a7b5f9ed2 /common/handle_error.cc | |
| parent | 2e6d0b752ab2d269f822bfd3ea029b100ecf4233 (diff) | |
| parent | d3f19cc27ea4634a64821688e9adec6046f4d7de (diff) | |
| download | nextpnr-d0ee08aeb12a8fb7237b31083666d9b165f13f69.tar.gz nextpnr-d0ee08aeb12a8fb7237b31083666d9b165f13f69.tar.bz2 nextpnr-d0ee08aeb12a8fb7237b31083666d9b165f13f69.zip | |
Merge branch 'master' into gqtech
Diffstat (limited to 'common/handle_error.cc')
| -rw-r--r-- | common/handle_error.cc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/common/handle_error.cc b/common/handle_error.cc new file mode 100644 index 00000000..a06b5348 --- /dev/null +++ b/common/handle_error.cc @@ -0,0 +1,56 @@ +#include <boost/python.hpp> +#include <Python.h> + +namespace py = boost::python; + +// Parses the value of the active python exception +// NOTE SHOULD NOT BE CALLED IF NO EXCEPTION +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){ + py::handle<> h_type(type_ptr); + py::str type_pstr(h_type); + // Extract the string from the boost::python object + py::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){ + py::handle<> h_val(value_ptr); + py::str a(h_val); + py::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){ + py::handle<> h_tb(traceback_ptr); + // Load the traceback module and the format_tb function + py::object tb(py::import("traceback")); + py::object fmt_tb(tb.attr("format_tb")); + // Call format_tb to get a list of traceback strings + py::object tb_list(fmt_tb(h_tb)); + // Join the traceback strings into a single string + py::object tb_str(py::str("\n").join(tb_list)); + // Extract the string, check the extraction, and fallback in necessary + py::extract<std::string> returned(tb_str); + if(returned.check()) + ret += ": " + returned(); + else + ret += std::string(": Unparseable Python traceback"); + } + return ret; +} |
