GriMel
GriMel

Reputation: 2320

Catch PyQt exceptions

I want to log all errors from my PyQt app. Even those, which are silenced - raised, but program keeps running.
So, I have:

Logging function

def setLogger(level=logging.DEBUG,
              name="my_logger",
              file=join("src", "log.out")):
    logger = logging.getLogger(name)
    logger.setLevel(level)

    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    formatter = logging.Formatter('%(message)s')
    ch.setFormatter(formatter)

    fh = logging.FileHandler(file)
    fh.setLevel(level)
    formatter = logging.Formatter(
        '%(asctime)s : %(message)s',
        datefmt='%m/%d/%Y %I:%M:%S %p')
    fh.setFormatter(formatter)

    logger.addHandler(ch)
    logger.addHandler(fh)
    return logger

Sys.excepthook for silenced exceptions

sys._excepthook = sys.excepthook
    def exception_hook(exctype, value, traceback):
        sys._excepthook(exctype, value, traceback)
        sys.exit(1)
    sys.excepthook = exception_hook

And then I try to do something like this

def main():
    app = QtGui.QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    logger.info("New session started")
    try:
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    except Exception:
        logger.exception("Got error in MainWindow")

And somwewhere in MainWindow

try:
    dialog = MyDialog(somedata, somedata)
    dialog.closed.connect(self.doSomething)
    dialog.exec_()
except Exception:
    self.logger.exception("Got error in Dialog module")
    sys.exit()

Manually raise Exception

class MyDialog(QtGui.QDialog):
    def __init__(self):
        super(MyDialog, self).__init__()
        raise Exception

Everything goes as expected...almost.
Instead of 1 message I get 4!

What am I doing wrong and how to change this?

Upvotes: 3

Views: 1846

Answers (1)

GriMel
GriMel

Reputation: 2320

This issue had nothing to do either with PyQt or exceptions but with my stupidity :).
Every my class has its own logger, which gets initialized like this

self.logger = setLogger()

The problem was that I hadn't given them their own names, so at once I had 4 loggers with the same name = my_logger. After I set different names to all my loggers - the issue is gone.

class MyDialog(QtGui.QDialog):
  def __init__():
     super(MyDialog, self).__init__()
     self.logger = setLogger("dialog_logger")
[...]

class MyWindow(QtGui.QMainWindow):
  def __init__():
     super(MyWindow, self).__init__()
     self.logger = setLogger("window_logger")
[...]
#and so on

Upvotes: 1

Related Questions