pythonexceptiontkintertraceback

How to get full stack trace from Tkinter Tk.report_callback_exception?


Whenever I get an error in my Tkinter application, I would like to get a full stack trace of where the error occurred, through all of the functions the program is currently in.

Before my root window opens, I have Tk.report_callback_exception = TKINTERERROR and I am able to get the traceback object of the error in TKINTERERROR(). However, when I attempt to print the traceback (with traceback.format_list(traceback.extract_tb(tracebackObject))), it only gives me the most recent function call, and the line the error occurred on. Is this all that is possible with Tkinter exceptions, or is there a way to get the entire stack trace?

To elaborate, what I expect to get is something like this, in which all the functions the program is currently in are given:

Traceback (most recent call last):
  File "myfilepath", line 13, in <module>
    func1()
  File "myfilepath", line 2, in func1
    func2()
  File "myfilepath", line 5, in func2
    func3()
  File "myfilepath", line 8, in func3
    func4()
  File "myfilepath", line 11, in func4
    0/0
ZeroDivisionError: division by zero

However, I actually only get this:

File "...Python311\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
File "myfilepath.py", line 1898, in <lambda>
    widgetMethod(arguments, command = lambda: MyFunction(arguments))
                                                                                                                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "myfilepath", line 2465, in MyFunction
    0/0
    ~^~

My problem is that I would like to get the full stack trace, but I am only given the most recent function called.


Solution

  • This can be done by redefining the default TKINTERERROR() function:

    from tkinter import *
    import traceback
    
    Tk.report_callback_exception = TKINTERERROR
    
    #These arguments are supplied automatically and must be here
    def TKINTERERROR(tkinterLibrary, errorClass, finalErrorMessage, tracebackObject):
         '''Prints stack trace of Tkinter error and enters Python debugger.'''
         print('\n' + str(errorClass) + ':\n' + traceback.format_exc() + '\n' + str(finalErrorMessage) + '\n')
         import pdb; pdb.post_mortem(tracebackObject)