forked from Framework-R-D/phlex
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrorwrap.cpp
More file actions
108 lines (94 loc) · 2.6 KB
/
errorwrap.cpp
File metadata and controls
108 lines (94 loc) · 2.6 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "wrap.hpp"
#include <string>
// This code has excluded several error checking paths from code coverage,
// because the conditions to create the errors (trace formatting problems)
// are rare and too hard to recreate in a test, while the resolution (fall
// back to a generic error messsage) is rather straightforward and thus
// does not need testing.
using namespace phlex::experimental;
static bool format_traceback(std::string& msg,
#if PY_VERSION_HEX < 0x30c000000
PyObject* type,
PyObject* value,
PyObject* traceback)
#else
PyObject* exception)
#endif
{
PyObject* tbmod = PyImport_ImportModule("traceback");
PyObject* format_exception = PyObject_GetAttrString(tbmod, "format_exception");
Py_DECREF(tbmod);
PyObject* formatted_tb = PyObject_CallFunctionObjArgs(
#if PY_VERSION_HEX < 0x30c000000
format_exception, type, value, traceback, nullptr);
#else
format_exception, exception, nullptr);
#endif
Py_DECREF(format_exception);
// LCOV_EXCL_START
if (!formatted_tb) {
PyErr_Clear();
return false;
}
// LCOV_EXCL_STOP
PyObject* py_msg_empty = PyUnicode_FromString("");
PyObject* py_msg = PyUnicode_Join(py_msg_empty, formatted_tb);
Py_DECREF(py_msg_empty);
Py_DECREF(formatted_tb);
// LCOV_EXCL_START
if (!py_msg) {
PyErr_Clear();
return false;
}
// LCOV_EXCL_STOP
char const* c_msg = PyUnicode_AsUTF8(py_msg);
// LCOV_EXCL_START
if (c_msg) {
msg = c_msg;
Py_DECREF(py_msg);
return true;
}
// LCOV_EXCL_STOP
PyErr_Clear();
Py_DECREF(py_msg);
return false;
}
bool phlex::experimental::msg_from_py_error(std::string& msg, bool check_error)
{
PyGILRAII g;
if (check_error) {
if (!PyErr_Occurred())
return false;
}
#if PY_VERSION_HEX < 0x30c000000
PyObject *type = nullptr, *value = nullptr, *traceback = nullptr;
PyErr_Fetch(&type, &value, &traceback);
if (value) {
bool tb_ok = format_traceback(msg, type, value, traceback);
// LCOV_EXCL_START
if (!tb_ok) {
PyObject* pymsg = PyObject_Str(value);
msg = PyUnicode_AsUTF8(pymsg);
Py_DECREF(pymsg);
}
// LCOV_EXCL_STOP
} else {
msg = "unknown Python error occurred";
}
Py_XDECREF(traceback);
Py_XDECREF(value);
Py_XDECREF(type);
#else
PyObject* exc = PyErr_GetRaisedException();
if (exc) {
bool tb_ok = format_traceback(msg, exc);
if (!tb_ok) {
PyObject* pymsg = PyObject_Str(exc);
msg = PyUnicode_AsUTF8(pymsg);
Py_DECREF(pymsg);
}
Py_DECREF(exc);
}
#endif
return true;
}