I have developed several Python programs for others that use Tkinter to receive input from the user. In order to keep things simple and user-friendly, the command line or python console are never brought up (ie. .pyw files are used), so I'm looking into using the logging library to write error text to a file when an exception occurs. However, I'm having difficulty getting it to actually catch the exceptions. For example:
We write a function that will cause an error:
def cause_an_error():
a = 3/0
Now we try to log the error normally:
import logging
logging.basicConfig(filename='errors.log', level=logging.ERROR)
try:
cause_an_error()
except:
logging.exception('simple-exception')
As expected, the program errors, and logging writes the error to errors.log. Nothing appears in the console. However, there is a different result when we implement a Tkinter interface, like so:
import logging
import Tkinter
logging.basicConfig(filename='errors.log', level=logging.ERROR)
try:
root = Tkinter.Tk()
Tkinter.Button(root, text='Test', command=cause_an_error).pack()
root.mainloop()
except:
logging.exception('simple-exception')
In this case, pressing the button in the Tkinter window causes the error. However, this time, nothing is written to the file, and the following error appears in the console:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__
return self.func(*args)
File "C:/Users/samk/Documents/GitHub/sandbox/sandbox2.pyw", line 8, in cause_an_error
a = 3/0
ZeroDivisionError: integer division or modulo by zero
Is there a different way to catch and log this error?
It's not very well documented, but tkinter calls a method for exceptions that happen as the result of a callback. You can write your own method to do whatever you want by setting the attribute report_callback_exception on the root window.
For example:
import tkinter as tk
def handle_exception(exception, value, traceback):
print("Caught exception:", exception)
def raise_error():
raise Exception("Sad trombone!")
root = tk.Tk()
# setup custom exception handling
root.report_callback_exception=handle_exception
# create button that causes exception
b = tk.Button(root, text="Generate Exception", command=raise_error)
b.pack(padx=20, pady=20)
root.mainloop()
For reference:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With