mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Restore reporting of unhandled exceptions during GUI application startup on windows
Not as nice as it was previously since errors importing the site module will not be reported, but the python API provides no hooks for this in Py_RunMain
This commit is contained in:
parent
007b6d06ed
commit
1c13f9634c
@ -170,6 +170,7 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
const wchar_t *basename, *module, *function;
|
const wchar_t *basename, *module, *function;
|
||||||
int argc;
|
int argc;
|
||||||
|
PyObject* (*calibre_os_module)(void);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t* const *argv;
|
wchar_t* const *argv;
|
||||||
#else
|
#else
|
||||||
@ -237,6 +238,11 @@ run_interpreter() {
|
|||||||
status = PyConfig_SetBytesArgv(&config, interpreter_data.argc, interpreter_data.argv);
|
status = PyConfig_SetBytesArgv(&config, interpreter_data.argc, interpreter_data.argv);
|
||||||
#endif
|
#endif
|
||||||
CHECK_STATUS;
|
CHECK_STATUS;
|
||||||
|
if (interpreter_data.calibre_os_module) {
|
||||||
|
if (PyImport_AppendInittab("calibre_os_module", interpreter_data.calibre_os_module) == -1) {
|
||||||
|
fatal("Failed to add calibre_os_module to the init table");
|
||||||
|
}
|
||||||
|
}
|
||||||
status = Py_InitializeFromConfig(&config);
|
status = Py_InitializeFromConfig(&config);
|
||||||
CHECK_STATUS;
|
CHECK_STATUS;
|
||||||
|
|
||||||
|
@ -85,4 +85,13 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
if sys.gui_app:
|
||||||
|
import traceback
|
||||||
|
import calibre_os_module
|
||||||
|
calibre_os_module.gui_error_message(
|
||||||
|
f"Unhandled exception running {sys.calibre_basename}",
|
||||||
|
traceback.format_exc())
|
||||||
|
raise
|
||||||
|
@ -115,6 +115,42 @@ redirect_out_stream(FILE *stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
gui_error_message(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *pt, *pm;
|
||||||
|
if (!PyArg_ParseTuple(args, "UU", &pt, &pm)) return NULL;
|
||||||
|
wchar_t title[256] = {0}, text[4096] = {0};
|
||||||
|
PyUnicode_AsWideChar(pt, title, arraysz(title)-1);
|
||||||
|
PyUnicode_AsWideChar(pm, text, arraysz(text)-1);
|
||||||
|
MessageBoxW(NULL, text, title, MB_ICONERROR|MB_OK);
|
||||||
|
return PyBool_FromLong(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef methods[] = {
|
||||||
|
{"gui_error_message", (PyCFunction)gui_error_message, METH_VARARGS,
|
||||||
|
"gui_error_message(title, msg) -> Show a GUI based error message."
|
||||||
|
},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct PyModuleDef module = {
|
||||||
|
/* m_base */ PyModuleDef_HEAD_INIT,
|
||||||
|
/* m_name */ "calibre_os_module",
|
||||||
|
/* m_doc */ "Integration with OS facilities during startup",
|
||||||
|
/* m_size */ -1,
|
||||||
|
/* m_methods */ methods,
|
||||||
|
/* m_slots */ 0,
|
||||||
|
/* m_traverse */ 0,
|
||||||
|
/* m_clear */ 0,
|
||||||
|
/* m_free */ 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
PyObject*
|
||||||
|
calibre_os_module(void) {
|
||||||
|
return PyModule_Create(&module);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
null_invalid_parameter_handler(
|
null_invalid_parameter_handler(
|
||||||
const wchar_t * expression,
|
const wchar_t * expression,
|
||||||
@ -151,6 +187,7 @@ execute_python_entrypoint(const wchar_t *basename, const wchar_t *module, const
|
|||||||
interpreter_data.argv = CommandLineToArgvW(GetCommandLineW(), &interpreter_data.argc);
|
interpreter_data.argv = CommandLineToArgvW(GetCommandLineW(), &interpreter_data.argc);
|
||||||
if (interpreter_data.argv == NULL) ExitProcess(show_last_error(L"Failed to get command line"));
|
if (interpreter_data.argv == NULL) ExitProcess(show_last_error(L"Failed to get command line"));
|
||||||
interpreter_data.basename = basename; interpreter_data.module = module; interpreter_data.function = function;
|
interpreter_data.basename = basename; interpreter_data.module = module; interpreter_data.function = function;
|
||||||
|
interpreter_data.calibre_os_module = calibre_os_module;
|
||||||
load_python_dll();
|
load_python_dll();
|
||||||
pre_initialize_interpreter(is_gui_app);
|
pre_initialize_interpreter(is_gui_app);
|
||||||
run_interpreter();
|
run_interpreter();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user