Search code examples
pythonexceptionpyqtpyqt5sys

How does the sys.excepthook function work with PyQt5?


I am working on a Python project which uses PyQt5 to create the GUI. I was having an issue where errors wouldn't terminate the program or send error messages; the program would just crash. While doing some research, I was able to find a snippet of code on Reddit that I added to my __init__ method. This solved my problem, but unfortunately the post didn't really elaborate on the solution, so I am not sure why this works.

While reading through the Python documentation, I understand that the sys.excepthook function essentially obtains the exception, and prints it out to the console, is this correct?

It looks like this piece of code is obtaining the exception from sys.excepthook and storing it in variable sys._excepthook, then defining function exception_hook which essentially calls sys.excepthook (through sys._excepthook).

My questions are:

1) Why is this needed? I understand that this is a known issue with PyQt where exceptions/error messages get "lost" and programs tend to crash.

2) How does this piece of code work to solve the problem?

sys._excepthook = sys.excepthook

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

sys.excepthook = exception_hook

Solution

  • The sys.excepthook is function called if exception occurs outside try: .... except. So if You would like to to manage it on your way You need to write own function.

    In my Application I do not meet problem with lost error information, but such exception do not terminate application.

    sys._excepthook = sys.excepthook # save original excepthook 
    
    def exception_hook(exctype, value, traceback):
        print(exctype, value, traceback) # print exception. 
        sys._excepthook(exctype, value, traceback) # call original excepthoot. I do not why 
        sys.exit(1) # terminate program if above do not do this
    
    sys.excepthook = exception_hook # overwrite default excepthook 
    

    If python 3 I suggest to change:

    import traceback
    import sys 
    
    
    def exception_hook(exctype, value, traceback):
        traceback_formated = traceback.format_exception(exctype, value, traceback)
        traceback_string = "".join(traceback_formated)
        print(traceback_string, file=sys.stderr)
        sys.exit(1)
    

    there is also sys.__excepthook__ docs which can be used.