Add hooks to send email when uncaught exception occurs
This commit is contained in:
parent
d83204495b
commit
fc58594699
|
@ -25,7 +25,13 @@ WuttaPOS app
|
|||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
from collections import OrderedDict
|
||||
from traceback import format_exception
|
||||
|
||||
from rattail import app as base
|
||||
from rattail.config import make_config
|
||||
|
@ -37,6 +43,9 @@ import wuttapos
|
|||
from wuttapos.util import get_pos_batch_handler
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WuttaAppHandler(base.AppHandler):
|
||||
"""
|
||||
Custom app handler for WuttaPOS
|
||||
|
@ -55,6 +64,61 @@ def main(page: ft.Page):
|
|||
config = make_config()
|
||||
app = config.get_app()
|
||||
model = app.model
|
||||
handler = get_pos_batch_handler(config)
|
||||
|
||||
# nb. as of python 3.10 the original hook is accessible, we needn't save the ref
|
||||
# cf. https://docs.python.org/3/library/threading.html#threading.__excepthook__
|
||||
orig_thread_hook = threading.excepthook
|
||||
|
||||
hostname = socket.gethostname()
|
||||
email_context = OrderedDict([
|
||||
('hostname', hostname),
|
||||
('ipaddress', socket.gethostbyname(hostname)),
|
||||
('terminal', handler.get_terminal_id() or '??'),
|
||||
])
|
||||
|
||||
def send_error_email(traceback):
|
||||
extra_context = OrderedDict(email_context)
|
||||
|
||||
try:
|
||||
uuid = page.session.get('user_uuid')
|
||||
if uuid:
|
||||
session = app.make_session()
|
||||
user = session.get(model.User, uuid)
|
||||
extra_context['username'] = user.username
|
||||
batch = handler.get_current_batch(user, create=False)
|
||||
if batch:
|
||||
extra_context['batchid'] = batch.id_str
|
||||
session.close()
|
||||
else:
|
||||
extra_context['username'] = 'n/a'
|
||||
|
||||
app.send_email('uncaught_exception', {
|
||||
'extra_context': extra_context,
|
||||
'traceback': traceback,
|
||||
})
|
||||
|
||||
except:
|
||||
log.exception("failed to send error email")
|
||||
|
||||
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)
|
||||
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)
|
||||
orig_thread_hook(args)
|
||||
|
||||
# custom exception hook for main process
|
||||
sys.excepthook = sys_exc_hook
|
||||
|
||||
# custom exception hook for threads (requires python 3.8)
|
||||
# cf. https://docs.python.org/3/library/threading.html#threading.excepthook
|
||||
v = sys.version_info
|
||||
if v.major >= 3 and v.minor >= 8:
|
||||
threading.excepthook = thread_exc_hook
|
||||
|
||||
page.title = f"WuttaPOS v{wuttapos.__version__}"
|
||||
page.window_full_screen = True
|
||||
|
@ -137,7 +201,6 @@ def main(page: ft.Page):
|
|||
if user:
|
||||
page.session.set('user_uuid', uuid)
|
||||
page.session.set('user_display', str(user))
|
||||
handler = get_pos_batch_handler(config)
|
||||
batch = handler.get_current_batch(user, create=False)
|
||||
if batch:
|
||||
page.session.set('txn_display', batch.id_str)
|
||||
|
|
|
@ -657,7 +657,7 @@ 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'):
|
||||
def meta_button(text, on_click=None, bgcolor='blue', data=None):
|
||||
return ft.Container(content=ft.Text(text, size=meta_font_size,
|
||||
weight=ft.FontWeight.BOLD),
|
||||
height=meta_button_height,
|
||||
|
@ -666,7 +666,8 @@ class POSView(WuttaView):
|
|||
alignment=ft.alignment.center,
|
||||
border=ft.border.all(1, 'black'),
|
||||
border_radius=ft.border_radius.all(5),
|
||||
bgcolor=bgcolor)
|
||||
bgcolor=bgcolor,
|
||||
data=data)
|
||||
|
||||
self.meta_menu = ft.Container(
|
||||
content=ft.Column(
|
||||
|
@ -695,7 +696,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),
|
||||
meta_button("TODO", bgcolor='blue', on_click=self.not_supported,
|
||||
data={'error': True}),
|
||||
],
|
||||
spacing=0,
|
||||
),
|
||||
|
@ -867,6 +869,11 @@ class POSView(WuttaView):
|
|||
self.page.update()
|
||||
|
||||
def not_supported(self, e=None, feature=None):
|
||||
|
||||
# test error handler
|
||||
if e.control.data and e.control.data.get('error'):
|
||||
raise ValueError("NOT YET SUPPORTED")
|
||||
|
||||
text = "NOT YET SUPPORTED"
|
||||
if not feature and e:
|
||||
feature = e.control.content.value
|
||||
|
|
Loading…
Reference in a new issue