- ename = "(unknown exception)";
-
- /* Send the exception error message(s) to srd_err(). */
- py_str_as_str(py_str, &str);
- g_string_append(msg, ename);
- g_string_append(msg, ": ");
- g_string_append(msg, str);
- Py_DecRef(py_str);
- srd_err(msg->str);
-
- /* Send a more precise error location to srd_dbg(), if we have it. */
- if (etb && etb != Py_None) {
- tracestr = NULL;
- py_tb = (PyTracebackObject *) etb;
- py_str = PyUnicode_FromFormat("%U:%d in %U",
- py_tb->tb_frame->f_code->co_filename,
- py_tb->tb_frame->f_lineno,
- py_tb->tb_frame->f_code->co_name);
- py_str_as_str(py_str, &tracestr);
- Py_DecRef(py_str);
- g_string_printf(msg, "%s in %s: %s", ename, tracestr, str);
- srd_dbg(msg->str);
- g_free(tracestr);
+ srd_err("%s: %s.", etype_name_fallback, msg);
+
+ g_free(evalue_str);
+ g_free(etype_name);
+
+ /* If there is no traceback object, we are done. */
+ if (!py_etraceback)
+ goto cleanup;
+
+ py_mod = py_import_by_name("traceback");
+ if (!py_mod)
+ goto cleanup;
+
+ py_func = PyObject_GetAttrString(py_mod, "format_exception");
+ if (!py_func || !PyCallable_Check(py_func))
+ goto cleanup;
+
+ /* Call into Python to format the stack trace. */
+ py_tracefmt = PyObject_CallFunctionObjArgs(py_func,
+ py_etype, py_evalue, py_etraceback, NULL);
+ if (!py_tracefmt)
+ goto cleanup;
+
+ tracefmt_str = py_stringify(py_tracefmt);
+ Py_DECREF(py_tracefmt);
+
+ /* Log the detailed stack trace. */
+ if (tracefmt_str) {
+ srd_dbg("%s", tracefmt_str);
+ g_free(tracefmt_str);