From cd392fa4324ae8552800fd00593c820d502a5d45 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 29 Sep 2023 12:32:06 -0500 Subject: [PATCH] Show alert on-screen when uncaught exception happens --- wuttapos/app.py | 50 +++++++++++++++++++++++++++++++++++++------ wuttapos/util.py | 16 ++++++++++++++ wuttapos/views/pos.py | 11 +++++----- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/wuttapos/app.py b/wuttapos/app.py index a06393e..4e76d98 100644 --- a/wuttapos/app.py +++ b/wuttapos/app.py @@ -40,7 +40,7 @@ from rattail.files import resource_path import flet as ft import wuttapos -from wuttapos.util import get_pos_batch_handler +from wuttapos.util import get_pos_batch_handler, make_button log = logging.getLogger(__name__) @@ -77,8 +77,9 @@ def main(page: ft.Page): ('terminal', handler.get_terminal_id() or '??'), ]) - def send_error_email(traceback): + def handle_error(exc_type, exc_value, exc_traceback): extra_context = OrderedDict(email_context) + traceback = ''.join(format_exception(exc_type, exc_value, exc_traceback)).strip() try: uuid = page.session.get('user_uuid') @@ -101,14 +102,51 @@ def main(page: ft.Page): except: log.exception("failed to send error email") + try: + def close_bs(e): + bs.open = False + bs.update() + + bs = ft.BottomSheet( + ft.Container( + ft.Column( + [ + ft.Text("Unexpected Error", size=24, + weight=ft.FontWeight.BOLD), + ft.Divider(), + ft.Text("Please be advised, something unexpected has gone wrong.\n" + "The state of your transaction may be questionable.\n\n" + "If possible you should consult the IT administrator.\n" + "(They may have already received an email about this.)", + size=20), + ft.Container( + content=make_button("Dismiss", on_click=close_bs, + height=80, width=120), + alignment=ft.alignment.center, + expand=1, + ), + ], + ), + bgcolor='yellow', + padding=20, + ), + open=True, + ) + + page.overlay.append(bs) + page.update() + + except: + log.exception("failed to show error bottomsheet") + def sys_exc_hook(exc_type, exc_value, exc_traceback): - traceback = ''.join(format_exception(exc_type, exc_value, exc_traceback)).strip() - send_error_email(traceback) + handle_error_email(exc_type, exc_value, exc_traceback) sys.__excepthook__(exc_type, exc_value, exc_traceback) def thread_exc_hook(args): - traceback = ''.join(format_exception(args.exc_type, args.exc_value, args.exc_traceback)).strip() - send_error_email(traceback) + handle_error(args.exc_type, args.exc_value, args.exc_traceback) + # nb. as of python 3.10 could just call threading.__excepthook__ instead + # cf. https://docs.python.org/3/library/threading.html#threading.__excepthook__ orig_thread_hook(args) # custom exception hook for main process diff --git a/wuttapos/util.py b/wuttapos/util.py index ad4fc9f..ef994b3 100644 --- a/wuttapos/util.py +++ b/wuttapos/util.py @@ -24,6 +24,8 @@ WuttaPOS utilities """ +import flet as ft + def get_pos_batch_handler(config): """ @@ -34,3 +36,17 @@ def get_pos_batch_handler(config): """ app = config.get_app() return app.get_batch_handler('pos', default='rattail.batch.pos:POSBatchHandler') + + +def make_button(text, font_size=24, font_bold=True, font_weight=None, **kwargs): + """ + Generic function for making a Container button. + """ + if not font_weight and font_bold: + font_weight = ft.FontWeight.BOLD + text = ft.Text(text, size=font_size, weight=font_weight) + + kwargs.setdefault('alignment', ft.alignment.center) + kwargs.setdefault('border', ft.border.all(1, 'black')) + kwargs.setdefault('border_radius', ft.border_radius.all(5)) + return ft.Container(content=text, **kwargs) diff --git a/wuttapos/views/pos.py b/wuttapos/views/pos.py index a667a28..f16435a 100644 --- a/wuttapos/views/pos.py +++ b/wuttapos/views/pos.py @@ -657,8 +657,9 @@ class POSView(WuttaView): meta_button_width = meta_button_height * 2 meta_font_size = tenkey_font_size - def meta_button(text, on_click=None, bgcolor='blue', data=None): - return ft.Container(content=ft.Text(text, size=meta_font_size, + def meta_button(text, on_click=None, bgcolor='blue', data=None, + font_size=None): + return ft.Container(content=ft.Text(text, size=font_size or meta_font_size, weight=ft.FontWeight.BOLD), height=meta_button_height, width=meta_button_width, @@ -696,8 +697,8 @@ class POSView(WuttaView): ft.Row( [ meta_button("TODO", bgcolor='blue', on_click=self.not_supported), - meta_button("TODO", bgcolor='blue', on_click=self.not_supported, - data={'error': True}), + meta_button("(TEST ERROR)", bgcolor='red', on_click=self.not_supported, + font_size=24, data={'error': True}), ], spacing=0, ), @@ -872,7 +873,7 @@ class POSView(WuttaView): # test error handler if e.control.data and e.control.data.get('error'): - raise ValueError("NOT YET SUPPORTED") + raise RuntimeError("NOT YET SUPPORTED") text = "NOT YET SUPPORTED" if not feature and e: