From: Stefan Bund Date: Fri, 14 Jun 2013 19:47:27 +0000 (+0200) Subject: catch and display errors in initialization code X-Git-Url: http://g0dil.de/git?p=pykit.git;a=commitdiff_plain;h=e69bad4506b90ec282f532b695273156df6016b0 catch and display errors in initialization code --- diff --git a/PythonPublisher.cc b/PythonPublisher.cc index f84b8da..f1699d4 100644 --- a/PythonPublisher.cc +++ b/PythonPublisher.cc @@ -433,6 +433,16 @@ namespace { return pykit::Viewer::instance()->page()->history()->canGoForward(); } + class ErrorCatcher + { + public: + explicit ErrorCatcher(std::string & out) : out_ (out) {} + void write(std::string const & msg) + { std::cerr << "append: " << msg; out_ += msg; } + private: + std::string & out_; + }; + } BOOST_PYTHON_MODULE(_pykit) @@ -454,6 +464,10 @@ BOOST_PYTHON_MODULE(_pykit) .def("publish", py::pure_virtual(&pykit::Publisher::publish)) ; + py::class_("ErrorCatcher", py::no_init) + .def("write", &ErrorCatcher::write) + ; + py::def("openUrl", &QDesktopServices::openUrl); py::def("canGoBack", &canGoBack); @@ -465,18 +479,28 @@ PYTHON_EXTERN_MODULE(_httpapi); prefix_ pykit::PythonPublisher::PythonPublisher() : impl_ (new Impl) { + std::string pyError; try { PYTHON_PREPARE_IMPORT(_pykit); PYTHON_PREPARE_IMPORT(_qt); PYTHON_PREPARE_IMPORT(_httpapi); Py_Initialize(); - py::object initModule = py::import("init"); + + py::import("_pykit"); + py::object sysModule (py::import("sys")); + py::object origStderr (sysModule.attr("stderr")); + ErrorCatcher catcher (pyError); + sysModule.attr("stderr") = catcher; + + py::object initModule (py::import("init")); impl_->mainNamespace = py::extract(initModule.attr("__dict__")); impl_->pythonPublisher = py::extract(impl_->mainNamespace["initialize"]()); + + sysModule.attr("stderr") = origStderr; } catch (boost::python::error_already_set & ex) { PyErr_Print(); - throw; + throw PythonError(pyError); } } @@ -495,6 +519,7 @@ prefix_ void pykit::PythonPublisher::publish(Request & request) } catch (py::error_already_set & ex) { PyErr_Print(); + PyErr_Clear(); } } diff --git a/PythonPublisher.hh b/PythonPublisher.hh index 1065a38..3238cac 100644 --- a/PythonPublisher.hh +++ b/PythonPublisher.hh @@ -18,6 +18,16 @@ namespace pykit { + class PythonError + : public std::exception + { + public: + virtual char const * what() const throw() { return message.c_str(); } + std::string message; + PythonError(std::string message_) : message (message_) {} + virtual ~PythonError() throw() {} + }; + class PythonPublisher : public Publisher { diff --git a/main.cc b/main.cc index c4d4910..52a540d 100644 --- a/main.cc +++ b/main.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "MainWindow.hh" #include "PythonPublisher.hh" @@ -37,13 +38,25 @@ namespace { return QSize(); return QSize(coords[0].toInt(), coords[1].toInt()); } + + void showPlatformError(char const * reason) + { + QMessageBox msgBox; + msgBox.setText("Es ist ein interner Fehler bei der Initialisierung" + " aufgetreten. Bitte notieren sie die folgende" + " Fehlermeldung und weden sie sich an den technischen" + " Support."); + msgBox.setDetailedText(reason); + msgBox.setInformativeText(QString("%1 wird beendet.").arg(QApplication::applicationName())); + msgBox.setWindowTitle(QApplication::applicationName()); + msgBox.exec(); + } } int main(int argc, char *argv[]) { + QApplication app (argc, argv); try { - QApplication app (argc, argv); - QSettings settings ("pykit.ini", QSettings::IniFormat); QStringList arguments (app.arguments()); settings.beginGroup("AppData"); @@ -110,9 +123,15 @@ int main(int argc, char *argv[]) return app.exec(); } - catch (std::exception & ex) { + catch (std::exception const & ex) { std::cerr << "Exception:\n" << ex.what() << "\n"; - throw; + showPlatformError(ex.what()); + return 1; + } + catch (...) { + std::cerr << "Exception: \n"; + showPlatformError("undefined error condition"); + return 1; } }