diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index 5197b86d..63d09d28 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -362,6 +362,20 @@ class NetworkMismatchErrorView(ErrorView): class UnhandledExceptionView(View): error: list[str] + def __post_init__(self): + from seedsigner.hardware.camera import CameraConnectionError + super().__post_init__() + + # Camera errors bubble up to here. Reroute to their custom error View. + if self.error[0] == CameraConnectionError.__name__: + self.set_redirect( + Destination( + CameraConnectionErrorView, + skip_current_view=True, + ) + ) + + def run(self): self.run_screen( ErrorScreen, @@ -376,6 +390,21 @@ class UnhandledExceptionView(View): +@dataclass +class CameraConnectionErrorView(View): + def run(self): + self.run_screen( + ErrorScreen, + title=_("Hardware Error"), + status_headline=_("Cannot access camera"), + text=_("Disconnect power and check for a loose camera connection."), + button_data=[ButtonOption("Back to Main Menu")], + show_back_button=False, + ) + + return Destination(MainMenuView, clear_history=True) + + @dataclass class OptionDisabledView(View): UPDATE_SETTING = ButtonOption("Update setting") diff --git a/tests/base.py b/tests/base.py index e89174ca..eaf46930 100644 --- a/tests/base.py +++ b/tests/base.py @@ -10,7 +10,7 @@ sys.modules['seedsigner.gui.screens.screensaver'] = MagicMock() sys.modules['seedsigner.gui.toast'] = MagicMock() sys.modules['seedsigner.views.screensaver'] = MagicMock() sys.modules['seedsigner.hardware.buttons'] = MagicMock() -sys.modules['seedsigner.hardware.camera'] = MagicMock() +sys.modules['seedsigner.hardware.camera.Camera'] = MagicMock() sys.modules['seedsigner.hardware.st7789_mpy'] = MagicMock() sys.modules['seedsigner.hardware.ili9341'] = MagicMock() diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index 2d3bbafd..5ab56d36 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -20,7 +20,7 @@ sys.modules['seedsigner.hardware.displays.ili9341'] = MagicMock() sys.modules['seedsigner.views.screensaver.ScreensaverScreen'] = MagicMock() sys.modules['RPi'] = MagicMock() sys.modules['RPi.GPIO'] = MagicMock() -sys.modules['seedsigner.hardware.camera'] = MagicMock() +sys.modules['seedsigner.hardware.camera.Camera'] = MagicMock() sys.modules['seedsigner.hardware.microsd'] = MagicMock() from seedsigner.controller import Controller @@ -42,7 +42,7 @@ from seedsigner.models.settings_definition import SettingsConstants, SettingsDef from seedsigner.views import (MainMenuView, PowerOptionsView, RestartView, NotYetImplementedView, UnhandledExceptionView, psbt_views, seed_views, settings_views, tools_views, scan_views) from seedsigner.views.screensaver import OpeningSplashView -from seedsigner.views.view import NetworkMismatchErrorView, OptionDisabledView, PowerOffView +from seedsigner.views.view import CameraConnectionErrorView, NetworkMismatchErrorView, OptionDisabledView, PowerOffView from .utils import ScreenshotComplete, ScreenshotConfig, ScreenshotRenderer @@ -414,7 +414,8 @@ def generate_screenshots(locale): ], "Misc Error Views": [ ScreenshotConfig(NotYetImplementedView), - ScreenshotConfig(UnhandledExceptionView, dict(error=["CameraConnectionError", "camera.py, 44, in start_video_stream_mode", "Camera error. Check camera connection."])), + ScreenshotConfig(UnhandledExceptionView, dict(error=["IndexError", "line 1, in some_buggy_code.py", "list index out of range"])), + ScreenshotConfig(CameraConnectionErrorView), ScreenshotConfig(NetworkMismatchErrorView, dict(derivation_path="m/84'/1'/0'")), ScreenshotConfig(OptionDisabledView, dict(settings_attr=SettingsConstants.SETTING__MESSAGE_SIGNING)), ScreenshotConfig(scan_views.ScanInvalidQRTypeView)