From ec2b5f0b0dc3a1f159016bf24b9cb9303290dfb8 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Thu, 29 Aug 2024 08:56:56 +0200 Subject: [PATCH] improve error handling for the case the database can not be reached --- src/EzLanManager.py | 44 ++++++++++- src/ez_lan_manager/pages/DbErrorPage.py | 78 +++++++++++++++++++ src/ez_lan_manager/pages/__init__.py | 1 + .../services/DatabaseService.py | 7 +- 4 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/ez_lan_manager/pages/DbErrorPage.py diff --git a/src/EzLanManager.py b/src/EzLanManager.py index d8e31d8..2ece807 100644 --- a/src/EzLanManager.py +++ b/src/EzLanManager.py @@ -1,12 +1,14 @@ import logging +import sys from pathlib import Path from rio import App, Theme, Color, Font, Page, Session from from_root import from_root -from src.ez_lan_manager import pages, init_services +from src.ez_lan_manager import pages, init_services, ConfigurationService from src.ez_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard +from src.ez_lan_manager.services.DatabaseService import NoDatabaseConnectionError from src.ez_lan_manager.types.SessionStorage import SessionStorage logger = logging.getLogger(__name__.split(".")[-1]) @@ -26,7 +28,43 @@ if __name__ == "__main__": font=Font(from_root("src/ez_lan_manager/assets/fonts/joystix.otf")) ) - services = init_services() + try: + services = init_services() + except NoDatabaseConnectionError: + configuration_service = ConfigurationService(from_root("config.toml")) + lan_info = configuration_service.get_lan_info() + app = App( + name="EZ LAN Manager", + pages=[ + Page( + name="DbErrorPage", + page_url="", + build=pages.DbErrorPage, + ) + ], + theme=theme, + default_attachments=[configuration_service], + assets_dir=Path(__file__).parent / "assets", + icon=from_root("src/ez_lan_manager/assets/img/favicon.png"), + meta_tags={ + "robots": "INDEX,FOLLOW", + "description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.", + "og:description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.", + "keywords": "Gaming, Clan, Guild, Verein, Club, Einfach, Zocken, Genuss, Gesellschaft, Videospiele, " + "Videogames, LAN, Party, EZ, LAN, Manager", + "author": "David Rodenkirchen", + "publisher": "EZ GG e.V.", + "copyright": "EZ GG e.V.", + "audience": "Alle", + "page-type": "Management Application", + "page-topic": "LAN Party", + "expires": "", + "revisit-after": "2 days" + } + ) + sys.exit(app.run_as_web_server()) + + lan_info = services[2].get_lan_info() async def on_session_start(session: Session) -> None: @@ -143,4 +181,4 @@ if __name__ == "__main__": } ) - app.run_as_web_server() + sys.exit(app.run_as_web_server()) diff --git a/src/ez_lan_manager/pages/DbErrorPage.py b/src/ez_lan_manager/pages/DbErrorPage.py new file mode 100644 index 0000000..33558a8 --- /dev/null +++ b/src/ez_lan_manager/pages/DbErrorPage.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from typing import * # type: ignore + +from rio import Component, event, Spacer, Card, Container, Column, Row, TextStyle, Color, Text + +from src.ez_lan_manager import ConfigurationService +from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox + + +class DbErrorPage(Component): + @event.on_window_size_change + async def on_window_size_change(self): + await self.force_refresh() + + def build(self) -> Component: + content = Card( + content=MainViewContentBox( + content=Text( + text="Ouh-oh, da läuft gerade irgendwas schief mit unserer Datenbank.\n\nUnser Team kümmert sich bereits um das Problem.", + margin=2, + style=TextStyle( + fill=self.session.theme.danger_color, + font_size=1.3 + ), + wrap=True + ) + ), + color="secondary", + min_width=38, + corner_radius=(0, 0.5, 0, 0) + ) + if self.session.window_width > 28: + return Container( + content=Column( + Column( + Row( + Spacer(grow_x=True, grow_y=True), + Card( + content=Spacer(), + color=self.session.theme.neutral_color, + min_width=15, + grow_y=True, + corner_radius=(0.5, 0, 0, 0), + margin_right=0.1 + ), + content, + Spacer(grow_x=True, grow_y=True), + grow_y=True + ), + Row( + Spacer(grow_x=True, grow_y=False), + Card( + content=Text(f"EZ LAN Manager Version {self.session[ConfigurationService].APP_VERSION} © EZ GG e.V.", align_x=0.5, align_y=0.5, style=TextStyle(fill=self.session.theme.primary_color, font_size=0.5)), + color=self.session.theme.neutral_color, + corner_radius=(0, 0, 0.5, 0.5), + grow_x=False, + grow_y=False, + min_height=1.2, + min_width=53.1, + margin_bottom=3 + ), + Spacer(grow_x=True, grow_y=False), + grow_y=False + ), + margin_top=4 + ) + ), + grow_x=True, + grow_y=True + ) + else: + return Text( + "Der EZ LAN Manager wird\nauf mobilen Endgeräten nur\nim Querformat unterstützt.\nBitte drehe dein Gerät.", + align_x=0.5, + align_y=0.5, + style=TextStyle(fill=Color.from_hex("FFFFFF"), font_size=0.8) + ) diff --git a/src/ez_lan_manager/pages/__init__.py b/src/ez_lan_manager/pages/__init__.py index fddb2d2..1950e63 100644 --- a/src/ez_lan_manager/pages/__init__.py +++ b/src/ez_lan_manager/pages/__init__.py @@ -12,3 +12,4 @@ from .FaqPage import FaqPage from .TournamentsPage import TournamentsPage from .GuestsPage import GuestsPage from .CateringPage import CateringPage +from .DbErrorPage import DbErrorPage diff --git a/src/ez_lan_manager/services/DatabaseService.py b/src/ez_lan_manager/services/DatabaseService.py index 943b81a..c5cf563 100644 --- a/src/ez_lan_manager/services/DatabaseService.py +++ b/src/ez_lan_manager/services/DatabaseService.py @@ -21,6 +21,9 @@ logger = logging.getLogger(__name__.split(".")[-1]) class DuplicationError(Exception): pass +class NoDatabaseConnectionError(Exception): + pass + class DatabaseService: def __init__(self, database_config: DatabaseConfiguration) -> None: self._database_config = database_config @@ -37,8 +40,8 @@ class DatabaseService: database=self._database_config.db_name ) except mariadb.Error as e: - logger.fatal(f"Error connecting to database: {e}") - sys.exit(1) + logger.error(f"Error connecting to database: {e}") + raise NoDatabaseConnectionError def _get_cursor(self) -> Cursor: return self._connection.cursor()