title: Python, tkinter and imported classes: logging uncaught exceptions
body: <p>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.</p>
  
  <p>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 <a href="https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python">this</a> and <a href="https://stackoverflow.com/questions/20714644/python-sys-excepthook-and-logging-uncaught-exceptions-across-multiple-modules">this</a>. It seems that the sys.excepthook is just not getting called, either when I run it from IDLE or from the Command Prompt.</p>
  
  <p>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)</p>
  
  <p>Here is the code that I am trying to get to work, the main module:</p>
  
  <pre><code>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('&lt;&lt;&lt;&lt;&lt; STARTING NEW INSTANCE &gt;&gt;&gt;&gt;&gt;')
  
  # 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("&lt;&lt;&lt; Exception occurred at " + str(datetime.datetime.now()) + " &gt;&gt;&gt;")
          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()
  </code></pre>
  
  <p>And a submodule:</p>
  
  <pre><code>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]
  </code></pre>
  
  <p>What I expect to get is one file with all the general logging and a separate file with the exceptions and stacktraces.</p>
  
  <p>I will be eternally grateful if you can help me figure this out!</p>