28 PyGILState_STATE state = PyGILState_Ensure();
31 PyObject* pytype =
nullptr, *pyvalue =
nullptr, *pytrace =
nullptr;
32 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
33 if (pytype && pyvalue) {
34 const char* tname = PyExceptionClass_Name(pytype);
36 char* dot = strrchr((
char*)tname,
'.');
37 if (dot) tname = dot+1;
42 PyObject* msg = PyObject_Str(pyvalue);
50 Py_XINCREF(traceback);
56 while (traceback && traceback != Py_None) {
57 PyObject* frame = PyObject_GetAttrString(traceback,
"tb_frame");
58 PyObject* code = PyObject_GetAttrString(frame,
"f_code");
66 Py_DECREF(filenameStr);
69 PyObject*
name = PyObject_GetAttrString(code,
"co_name");
75 PyObject* lineno = PyObject_GetAttrString(traceback,
"tb_lineno");
76 locLine = PyLong_AsLong(lineno);
79 if (locFile ==
"<string>") {
80 PyObject* nextTraceback = PyObject_GetAttrString(traceback,
"tb_next");
82 traceback = nextTraceback;
89 Py_XDECREF(traceback);
91 PyErr_Restore(pytype, pyvalue, pytrace);
94 fMsg =
"python exception";
96 if (!locFile.empty()) {
99 locFile = locFile.substr(locFile.find_last_of(
"/\\") + 1);
101 fMsg +=
" (at " + locFile +
":" + std::to_string(locLine);
103 if (locName !=
"<module>")
104 fMsg +=
" in " + locName;
110 PyGILState_Release(state);