mirror of https://github.com/Icinga/icinga2.git
Print backtrace for Python exceptions.
This commit is contained in:
parent
df79e4c2dc
commit
d0f263abb1
|
@ -98,18 +98,14 @@ void PythonInterpreter::ProcessCall(const ScriptTask::Ptr& task, const String& f
|
|||
PyObject *ptype, *pvalue, *ptraceback;
|
||||
|
||||
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
|
||||
PyObject *pstr_msg = PyObject_Str(pvalue);
|
||||
PyObject *pstr_tb = PyObject_Str(ptraceback);
|
||||
Py_DECREF(pvalue);
|
||||
PyErr_Clear();
|
||||
|
||||
String msg = PyString_AsString(pstr_msg);
|
||||
Py_DECREF(pstr_msg);
|
||||
String msg = m_Language->ExceptionInfoToString(ptype, pvalue, ptraceback);
|
||||
|
||||
String tb = PyString_AsString(pstr_tb);
|
||||
Py_DECREF(pstr_tb);
|
||||
Py_XDECREF(ptype);
|
||||
Py_XDECREF(pvalue);
|
||||
Py_XDECREF(ptraceback);
|
||||
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Error in Python script:" + msg + " at " + tb));
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Error in Python script:" + msg));
|
||||
}
|
||||
|
||||
Value vresult = PythonLanguage::MarshalFromPython(result);
|
||||
|
|
|
@ -44,6 +44,8 @@ PythonLanguage::PythonLanguage(void)
|
|||
|
||||
m_MainThreadState = PyThreadState_Get();
|
||||
|
||||
m_TracebackModule = PyImport_ImportModule("traceback");
|
||||
|
||||
m_NativeModule = Py_InitModule("ire", m_NativeMethodDef);
|
||||
|
||||
(void) PyThreadState_Swap(NULL);
|
||||
|
@ -200,6 +202,32 @@ Value PythonLanguage::MarshalFromPython(PyObject *value)
|
|||
}
|
||||
}
|
||||
|
||||
String PythonLanguage::ExceptionInfoToString(PyObject *type, PyObject *exc, PyObject *tb) const
|
||||
{
|
||||
PyObject *tb_dict = PyModule_GetDict(m_TracebackModule);
|
||||
PyObject *format_exception = PyDict_GetItemString(tb_dict, "format_exception");
|
||||
|
||||
if (!PyCallable_Check(format_exception))
|
||||
return "Failed to format exception information.";
|
||||
|
||||
PyObject *result = PyObject_CallFunctionObjArgs(format_exception, type, exc, tb);
|
||||
|
||||
Py_DECREF(format_exception);
|
||||
Py_DECREF(tb_dict);
|
||||
|
||||
if (!result || !PyString_Check(result)) {
|
||||
Py_XDECREF(result);
|
||||
|
||||
return "format_exception() returned something that is not a string.";
|
||||
}
|
||||
|
||||
String msg = PyString_AsString(result);
|
||||
|
||||
Py_DECREF(result);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args)
|
||||
{
|
||||
assert(PyString_Check(self));
|
||||
|
|
|
@ -49,9 +49,11 @@ public:
|
|||
static PyObject *MarshalToPython(const Value& value);
|
||||
static Value MarshalFromPython(PyObject *value);
|
||||
|
||||
String ExceptionInfoToString(PyObject *type, PyObject *exc, PyObject *tb) const;
|
||||
private:
|
||||
PyThreadState *m_MainThreadState;
|
||||
PyObject *m_NativeModule;
|
||||
PyObject *m_TracebackModule;
|
||||
static PythonInterpreter *m_CurrentInterpreter;
|
||||
|
||||
void RegisterNativeFunction(const String& name, const ScriptFunction::Ptr& function);
|
||||
|
|
Loading…
Reference in New Issue