I am writing some scripts that I want to share with my team, so I have been building in a bunch of logging so that it will be easier to debug if they encounter a crash somewhere since then I can see what exactly crashed.
General logging to a file is no issue, but I have an issue with uncaught exceptions. I have tried various things to get it to work, see for example this and this. It seems that the sys.excepthook is just not getting called, either when I run it from IDLE or from the Command Prompt.
Yesterday it log correctly if the exception occurred in the main module, but not if an exception occurred in an imported class. Now the exceptions don't get logged at all, I have no clue what I changed (so I installed Git today :-P)
Here is the code that I am trying to get to work, the main module:
import tkinter as tk
import sys
import traceback
import logging
import datetime
import exception_logging_test_imported_class as impclass
# Main Class
class ExceptMain(tk.Frame):
def __init__(self, parent):
logging.info('Start main')
tk.Frame.__init__(self, parent, relief='groove', bd=4)
self.parent = parent
self.pack()
tk.Label(self, text='This is the main class', bg='white').pack()
tk.Button(self, text='Start subframe', command=self.run).pack()
tk.Button(self, text='Throw main exception', command=self.throwex).pack()
tk.Button(self, text='Start imported class', command=self.start_import).pack()
# Function to start another frame, from this same file
def run(self):
logging.info('Run main function')
subclass = ExceptSubclass(self)
subclass.pack()
# Function to start an imported frame class
def start_import(self):
imported_class = impclass.ExtraClass(self)
imported_class.pack()
# Throw an exception
def throwex(self):
raise ValueError("Main is burning down")
#Another class in this file
class ExceptSubclass(tk.Frame):
def __init__(self, parent):
logging.info('Start subframe')
tk.Frame.__init__(self, parent, relief='groove', bd=4)
self.parent = parent
self.pack()
tk.Label(self, text='This is the subclass', bg='white').pack()
tk.Button(self, text='run sub function', command=self.script).pack()
tk.Button(self, text='Throw sub exception', command=self.throwexsub).pack()
# Run something
def script(self):
logging.info('Run subfunction')
tk.Label(self, text='Script has run').pack()
# Throw an exception
def throwexsub(self):
thing = []
thing[1]
# Use a logger object or just logging
logger_not_just_logging = False
if logger_not_just_logging:
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("ZZ_logging_test.log"))
else:
logging.basicConfig(filename='ZZ_logging_test.log', level=logging.DEBUG)
logging.info('<<<<< STARTING NEW INSTANCE >>>>>')
# This function needs to be called somehow when an uncaught exception happens
def exception_handler(etype, value, tb):
logging.exception("Uncaught exception: {0}".format(str(value)))
with open('ZZ_exception_test.log', 'a') as file:
file.write("<<< Exception occurred at " + str(datetime.datetime.now()) + " >>>")
traceback.print_exception(etype, value, tb, file=file)
# Install the hook
sys.excepthook = exception_handler
# Run the app
root = tk.Tk()
app = ExceptMain(root)
root.mainloop()
And a submodule:
import tkinter as tk
import logging
# This is an imported frame
class ExtraClass(tk.Frame):
def __init__(self, parent):
logging.info('Start imported frame')
tk.Frame.__init__(self, parent, relief='groove', bd=4)
self.parent = parent
self.pack()
tk.Label(self, text='This is an imported frame', bg='white').pack()
tk.Button(self, text='run imported frame function', command=self.script).pack()
tk.Button(self, text='Throw imported exception', command=self.throwexsub).pack()
# Imported frame has a function
def script(self):
logging.info('Run imported frame function')
tk.Label(self, text='Imported script has run').pack()
# Imported frame throws an exception
def throwexsub(self):
thing = []
thing[1]
What I expect to get is one file with all the general logging and a separate file with the exceptions and stacktraces.
I will be eternally grateful if you can help me figure this out!