-
Notifications
You must be signed in to change notification settings - Fork 0
/
Error.cpp
61 lines (57 loc) · 2.15 KB
/
Error.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <Python.h> // must be included first per Python C API rules
#include "Error.hpp"
#include <boost/python.hpp>
namespace pccl {
namespace python {
Error::Error()
{
// Taken from wiki.python.org/moin/boost.python/EmbeddingPython
using namespace boost::python;
PyObject *typeRaw, *valueRaw, *tracebackRaw;
PyErr_Fetch(&typeRaw, &valueRaw, &tracebackRaw);
PyErr_NormalizeException(&typeRaw, &valueRaw, &tracebackRaw);
handle<> htype(typeRaw), hvalue(allow_null(valueRaw)), htraceback(allow_null(tracebackRaw));
std::vector<std::string> traceback;
// Push back an empty string so that the traceback gets printed on a new line
// when boost::diagnostic_information is called so that all of the python lines
// are lined up as they would in a regular interpreter
traceback.push_back("");
// Prevent throwing an exception
if (!hvalue)
{
str typeError(htype);
extract<std::string> errorValue(typeError);
// Check if extraction worked
if (errorValue.check())
{
traceback.push_back(errorValue());
}
}
else
{
object tracebackModule(import("traceback"));
object format_exception(tracebackModule.attr("format_exception"));
list formatted_list(format_exception(htype,hvalue,htraceback));
boost::python::ssize_t items = len(formatted_list);
for (boost::python::ssize_t ii = 0; ii < items; ii++)
{
str line(formatted_list[ii]);
extract<std::string> value(line);
if (!value.check())
continue;
std::string parsed(value());
// Formatted lines comes with the newline in them. Remove them
// so that 'what' will work correctly and to_string(python_traceback)
// will just add them back in
std::string::size_type newlinePosition = parsed.find('\n');
if (newlinePosition != std::string::npos)
{
parsed.erase(newlinePosition);
}
traceback.push_back(parsed);
}
}
*this << traceback_list(traceback);
}
} // namespace python
} // namespace pccl