How to raise a message box in case of not handled Error in Python?

Question:

I have a huge in size Python script which takes much time for its
execution, runs in background and is started in a way that I can’t see
its printing output.

In order to to be able to get notified when the script is finished
I raise an appropriate message box, but if the script exits because
of an Error I won’t get notified.

Below a minimal code demonstrating what I am speaking about:

import math
try: 
    i = int('Oxff') 
except ValueError:
      ...             # some code handling the exception  
... ; pass ; ...      # some further code  
import no_such_module # in code not handled unexpected error 
... ; pass ; ...      # some further code  
# Message box notifying about successfull script run: 
from tkinter import Tk
root = Tk()
root.geometry('10x10+'+str(root.winfo_screenwidth()-10)+'+'+str(root.winfo_screenheight()-10))
from tkinter.messagebox import Message 
Message(title="Success", message="No Error", master=root).show()

So when my Python script fails due to an unexpected and therefore not
in code handled error I will not get notified at all.

I don’t want to enclose the entire script code with try: ... except: ...
in order to handle unexpected and in code not handled errors.

Is there in Python a way to write a function which will be run displaying a message box in case an unexpected error terminates the script?

Asked By: Claudio

||

Answers:

You can in Python write a notification function which will be run when
Python exits because of in code not handled Error using the builtin
atexit module. With the help of this module you can register functions
which will be executed at Python script exit.

Below code for a function which if executed at start of a Python script
will cause raising a message box when Python script exits:

def get_notified_about_error(): 
    import atexit
    global atexit_handler
    def atexit_handler():
        print("Script EXIT because of an ERROR")
        from tkinter import Tk
        root = Tk()
        root.geometry('10x10+'+str(root.winfo_screenwidth()-10)+'+'+str(root.winfo_screenheight()-10))
        from tkinter.messagebox import Message 
        Message(title="atexit_handler()", message="Error occured", master=root).show()
    atexit.register(atexit_handler)
get_notified_about_error()

In order to avoid running the registered atexit_handler() function
when the Python script exits without an error unregister the function
in the last line of the Python script with:

import atexit
atexit.unregister(atexit_handler)

Below the entire code which demonstrates the solution:

# REQUIRED HEADER:
def get_notified_about_error(): 
    import atexit
    global atexit_handler
    def atexit_handler():
        print("Script EXIT because of an ERROR")
        from tkinter import Tk
        root = Tk()
        root.geometry('10x10+'+str(root.winfo_screenwidth()-10)+'+'+str(root.winfo_screenheight()-10))
        from tkinter.messagebox import Message 
        Message(title="atexit_handler()", message="Error occured", master=root).show()
    atexit.register(atexit_handler)
get_notified_about_error()

# SCRIPT CODE: 
import math
try: 
    i = int('Oxff') 
except ValueError:
      ...             # some code handling the exception  
... ; pass ; ...      # some further code  
import no_such_module # in code not handled unexpected error 
... ; pass ; ...      # some further code  
# Message box notifying about successfull script run: 
from tkinter import Tk
root = Tk()
root.geometry('10x10+'+str(root.winfo_screenwidth()-10)+'+'+str(root.winfo_screenheight()-10))
from tkinter.messagebox import Message 
Message(title="Success", message="No Error", master=root).show()

# REQUIRED TRAILER:
import atexit
atexit.unregister(atexit_handler)

Answered By: Claudio

Swap in your own sys.excepthook to handle uncaught exceptions:

import sys
import traceback
from tkinter.messagebox import showerror


def oops(type, value, tb):
    showerror('Error', 'n'.join(traceback.format_exception(type, value, tb)))
    sys.exit(1)


sys.excepthook = oops


print(1 / 0)

pops up

enter image description here

Answered By: AKX
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.