Skip to content

Instantly share code, notes, and snippets.

@JamesTheAwesomeDude
Last active March 7, 2024 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesTheAwesomeDude/d95754d3a45e98858120bd6ea37bec09 to your computer and use it in GitHub Desktop.
Save JamesTheAwesomeDude/d95754d3a45e98858120bd6ea37bec09 to your computer and use it in GitHub Desktop.
Python tkinter make exceptions fatal
from contextlib import contextmanager
import tkinter as tk # https://stackoverflow.com/questions/66734619/no-module-named-tkinter#66735147
import tkinter.messagebox
# Two different approaches to handling mainloop errors in tkinter.
# 1. A context manager that will display errors in callbacks and initializers (RECOMMENDED)
# 2. A subclass of Tk that will only display errors in callbacks, not initializers
@contextmanager
def tk_fail_mainloop(root):
"Usage: with tk_fail_mainloop(tk.Tk()) as root: ..."
def report_callback_exception(self, exc_type, exc_value, traceback):
try:
self.__class__.report_callback_exception(self, exc_type, exc_value, traceback)
# Don't bother showing traceback in the error box
# because that'll be a lot of work *and* break native warning messages
# https://stackoverflow.com/posts/comments/137714401
tk.messagebox.showerror(message=f'{exc_type.__name__}: {exc_value}', master=self)
finally:
self.destroy()
root.report_callback_exception = report_callback_exception.__get__(root, root.__class__)
try:
yield root
except Exception as exc:
root.report_callback_exception(exc.__class__, exc, exc.__traceback__)
class _Tk(tk.Tk):
"Alternative to tk.Tk that handles **uncaught** errors appropriately"
def report_callback_exception(self, exc_type=RuntimeError, exc_value=None, traceback=None):
try:
super().report_callback_exception(exc_type, exc_value, traceback)
# Don't bother showing traceback in the error box
# because that'll be a lot of work *and* break native warning messages
# https://stackoverflow.com/posts/comments/137714401
tk.messagebox.showerror(exc_type.__name__, exc_value, master=self)
finally:
self.destroy()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment