]> Devi Nivas Git - 4180kiosk.git/commitdiff
Add exception handling
authorAdvaith Menon <noreply-git@bp4k.net>
Fri, 30 Jan 2026 21:04:14 +0000 (16:04 -0500)
committerAdvaith Menon <noreply-git@bp4k.net>
Fri, 30 Jan 2026 21:04:14 +0000 (16:04 -0500)
ohdisp/exception_dialog.py [new file with mode: 0644]
ohdisp/model.py
ohdisp/views.py

diff --git a/ohdisp/exception_dialog.py b/ohdisp/exception_dialog.py
new file mode 100644 (file)
index 0000000..3ef0e8f
--- /dev/null
@@ -0,0 +1,31 @@
+import os
+import sys
+import threading
+
+import tkinter as tk
+from tkinter import messagebox
+from tkinter.font import Font
+
+
+class ExceptionDialog(tk.Toplevel):
+    def __init__(self, parent, txt, *args, **kwargs):
+        super().__init__(parent, *args, **kwargs);
+
+        self.title("Unhandled Exception");
+        self.attributes("-topmost", True);
+        self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
+
+        sb = tk.Scrollbar(self);
+        sb.pack(side='right', fill='y')
+
+        te = tk.Text(self);
+        te.insert('end', txt);
+        te.pack(side='top', fill='both', expand=True)
+
+        te['yscrollcommand'] = sb.set
+        sb['command'] = te.yview
+
+        quit_btn = tk.Button(self, text="Quit",
+                             command=self.destroy,
+                             padx=5, pady=5)
+        quit_btn.pack(side='right')
index f59f41831dc4cb3105beb4ef8c429342515f6d37..7246cea20c1fcfe64571d5f8c7b2e51da41d9261 100644 (file)
@@ -1,14 +1,20 @@
 import time
+import traceback
 import datetime
 import os
 import subprocess
+import sys
+import _thread
 
 import tkinter as tk
+from tkinter import messagebox
 from tkinter.font import Font
 
 import urllib3
 import pyttsx3
 
+from .exception_dialog import ExceptionDialog
+
 class QueueModel(object):
     def __init__(self, config, *args, **kwargs):
         self._cfg = config;
@@ -25,7 +31,23 @@ class QueueModel(object):
 
         return result;
 
-    def thread(self, tk_parent):
+    def thread(self, tk_parent, root):
+        """Wraps the original thread with exception handling"""
+        try:
+            self._thread(tk_parent);
+        except Exception as e:
+            err = traceback.format_exception(e);
+            if root:
+                tl = ExceptionDialog(root, "\n".join(err))
+                root.wait_window(tl);
+            else:
+                messagebox.showerror('Unhandled Exception in Polling Thread',
+                                     "\n".join(err) + ("\n\n"
+                                     "The application will now quit."));
+            print("Crashing application\n" + "\n".join(err), file=sys.stderr);
+            _thread.interrupt_main();
+
+    def _thread(self, tk_parent):
         n_students = 0
         cur_students = [];
         self.build_elements(cur_students, tk_parent);
index 490fb0661e2d415cb735e32d7cb466406b4f7a75..cfb35c0de57d99f951ce6e52d7f6d7727705b5e4 100644 (file)
@@ -1,10 +1,14 @@
 import os
+import sys
 import threading
 
 import tkinter as tk
+from tkinter import messagebox
 from tkinter.font import Font
 from .model import QueueModel
 
+from .exception_dialog import ExceptionDialog
+
 from PIL import ImageTk, Image
 
 
@@ -27,7 +31,7 @@ class TADisplayFrame(tk.Frame):
                                fg=self._cnf.style.title__fgcolor);
         self._title.pack(side='top', anchor='n', fill='x');
 
-        self._frame = StudentCheckoffFrame(self, self._cnf);
+        self._frame = StudentCheckoffFrame(self, self._cnf, root=parent);
         self._frame.pack(side='right', fill="both");
         self._frame = TAPictureFrame(self, self._cnf);
         self._frame.pack(side='top', fill='both', expand=1);
@@ -60,7 +64,7 @@ class TAPictureFrame(tk.Frame):
 
 
 class StudentCheckoffFrame(tk.Frame):
-    def __init__(self, parent, config, *args, **kwargs):
+    def __init__(self, parent, config, *args, root=None, **kwargs):
         super().__init__(parent, *args, **kwargs);
 
         self._cnf = config;
@@ -85,7 +89,7 @@ class StudentCheckoffFrame(tk.Frame):
         self._actualframe.pack(side='top', fill='both', expand=1);
 
         t = threading.Thread(target=self._model.thread,
-                             args=(self._actualframe,),
+                             args=(self._actualframe, root),
                              daemon=True)
         t.start()
 
@@ -103,3 +107,11 @@ class Root(tk.Tk):
 
     def fullscreen(self):
         self.attributes("-fullscreen", True);
+
+    def report_callback_exception(self, *args):
+        err = traceback.format_exception(*args);
+        tl = ExceptionDialog(self, "\n".join(err))
+        self.wait_window(tl);
+        self.destroy();
+        print("Exiting application\n" + err, file=sys.stderr);
+        exit();