When running in debug mode, handle C++ exceptions raised in Qt slots, printing out some information about the exception

This commit is contained in:
Kovid Goyal 2012-09-18 12:11:37 +05:30
parent 5452c7e58a
commit e1c3e1905e
4 changed files with 34 additions and 4 deletions

View File

@ -13,7 +13,7 @@ from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt,
ORG_NAME = 'KovidsBrain' ORG_NAME = 'KovidsBrain'
APP_UID = 'libprs500' APP_UID = 'libprs500'
from calibre.constants import (islinux, iswindows, isbsd, isfrozen, isosx, from calibre.constants import (islinux, iswindows, isbsd, isfrozen, isosx,
config_dir, filesystem_encoding) plugins, config_dir, filesystem_encoding, DEBUG)
from calibre.utils.config import Config, ConfigProxy, dynamic, JSONConfig from calibre.utils.config import Config, ConfigProxy, dynamic, JSONConfig
from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import MetaInformation
from calibre.utils.date import UNDEFINED_DATE from calibre.utils.date import UNDEFINED_DATE
@ -764,6 +764,7 @@ class Application(QApplication):
if override_program_name: if override_program_name:
args = [override_program_name] + args[1:] args = [override_program_name] + args[1:]
qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args] qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args]
self.pi = plugins['progress_indicator'][0]
QApplication.__init__(self, qargs) QApplication.__init__(self, qargs)
global gui_thread, qt_app global gui_thread, qt_app
gui_thread = QThread.currentThread() gui_thread = QThread.currentThread()
@ -773,16 +774,26 @@ class Application(QApplication):
self._file_open_paths = [] self._file_open_paths = []
self._file_open_lock = RLock() self._file_open_lock = RLock()
self.setup_styles(force_calibre_style) self.setup_styles(force_calibre_style)
if DEBUG:
self.redirect_notify = True
if DEBUG:
def notify(self, receiver, event):
if self.redirect_notify:
self.redirect_notify = False
return self.pi.do_notify(receiver, event)
else:
ret = QApplication.notify(self, receiver, event)
self.redirect_notify = True
return ret
def load_calibre_style(self): def load_calibre_style(self):
# On OS X QtCurve resets the palette, so we preserve it explicitly # On OS X QtCurve resets the palette, so we preserve it explicitly
orig_pal = QPalette(self.palette()) orig_pal = QPalette(self.palette())
from calibre.constants import plugins
pi = plugins['progress_indicator'][0]
path = os.path.join(sys.extensions_location, 'calibre_style.'+( path = os.path.join(sys.extensions_location, 'calibre_style.'+(
'pyd' if iswindows else 'so')) 'pyd' if iswindows else 'so'))
pi.load_style(path, 'Calibre') self.pi.load_style(path, 'Calibre')
# On OSX, on some machines, colors can be invalid. See https://bugs.launchpad.net/bugs/1014900 # On OSX, on some machines, colors can be invalid. See https://bugs.launchpad.net/bugs/1014900
for role in (orig_pal.Button, orig_pal.Window): for role in (orig_pal.Button, orig_pal.Window):
c = orig_pal.brush(role).color() c = orig_pal.brush(role).color()

View File

@ -5,6 +5,7 @@
#include <QPluginLoader> #include <QPluginLoader>
#include <QStyle> #include <QStyle>
#include <QApplication> #include <QApplication>
#include <QDebug>
QProgressIndicator::QProgressIndicator(QWidget* parent, int size) QProgressIndicator::QProgressIndicator(QWidget* parent, int size)
: QWidget(parent), : QWidget(parent),
@ -145,3 +146,16 @@ int load_style(QString &path, QString &name) {
} }
return ret; return ret;
} }
bool do_notify(QObject *receiver, QEvent *event) {
try {
return QApplication::instance()->notify(receiver, event);
} catch (std::exception& e) {
qCritical() << "C++ exception thrown in slot: " << e.what();
} catch (...) {
qCritical() << "Unknown C++ exception thrown in slot";
}
qCritical() << "Receiver name:" << receiver->objectName() << "Receiver class:" << receiver->metaObject()->className() << "Event type: " << event->type();
return false;
}

View File

@ -100,3 +100,5 @@ private:
*/ */
int load_style(QString &path, QString &name); int load_style(QString &path, QString &name);
bool do_notify(QObject *receiver, QEvent *event);

View File

@ -8,6 +8,7 @@
%ModuleHeaderCode %ModuleHeaderCode
int load_style(QString &path, QString &name); int load_style(QString &path, QString &name);
bool do_notify(QObject *receiver, QEvent *event);
%End %End
class QProgressIndicator : QWidget { class QProgressIndicator : QWidget {
@ -57,3 +58,5 @@ protected:
int load_style(QString &path, QString &name); int load_style(QString &path, QString &name);
bool do_notify(QObject *receiver, QEvent *event);