diff --git a/software/src/nfc/nfc.py b/software/src/nfc/nfc.py index 01fd8b8..650c80c 100644 --- a/software/src/nfc/nfc.py +++ b/software/src/nfc/nfc.py @@ -6,6 +6,7 @@ Copyright (c) 2025 Matthias Blankertz import asyncio import time +from utils import safe_callback from mfrc522 import MFRC522 try: @@ -74,7 +75,7 @@ class Nfc: self.last_uid = uid self.last_uid_timestamp = time.ticks_us() if self.cb is not None and last_callback_uid != uid: - self.cb.onTagChange(uid) + safe_callback(lambda: self.cb.onTagChange(uid), "nfc tag change") last_callback_uid = uid await asyncio.sleep_ms(poll_interval_ms) diff --git a/software/src/utils/__init__.py b/software/src/utils/__init__.py index 3f5d65d..cdb1ec8 100644 --- a/software/src/utils/__init__.py +++ b/software/src/utils/__init__.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: MIT # Copyright (c) 2025 Matthias Blankertz +from utils.helpers import safe_callback from utils.buttons import Buttons from utils.config import Configuration from utils.leds import LedManager @@ -11,4 +12,4 @@ from utils.sdcontext import SDContext from utils.timer import TimerManager __all__ = ["BTreeDB", "BTreeFileManager", "Buttons", "Configuration", "get_pin_index", "LedManager", "MBRPartition", - "SDContext", "TimerManager"] + "safe_callback", "SDContext", "TimerManager"] diff --git a/software/src/utils/buttons.py b/software/src/utils/buttons.py index a1f1c6e..b6b5a24 100644 --- a/software/src/utils/buttons.py +++ b/software/src/utils/buttons.py @@ -5,6 +5,7 @@ import asyncio import machine import micropython import time +from utils import safe_callback try: from typing import TYPE_CHECKING # type: ignore except ImportError: @@ -74,4 +75,4 @@ class Buttons: await self.int_flag.wait() while len(self.pressed) > 0: what = self.pressed.pop() - self.cb.onButtonPressed(what) + safe_callback(lambda: self.cb.onButtonPressed(what), "button callback") diff --git a/software/src/utils/helpers.py b/software/src/utils/helpers.py new file mode 100644 index 0000000..afb91a6 --- /dev/null +++ b/software/src/utils/helpers.py @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2025 Matthias Blankertz + +import sys + + +def safe_callback(func, name="callback"): + try: + func() + except Exception as ex: + print(f"Uncaught exception in {name}") + sys.print_exception(ex) diff --git a/software/src/utils/timer.py b/software/src/utils/timer.py index e389ee5..301a7e6 100644 --- a/software/src/utils/timer.py +++ b/software/src/utils/timer.py @@ -4,6 +4,7 @@ import asyncio import heapq import time +from utils import safe_callback TIMER_DEBUG = True @@ -72,5 +73,7 @@ class TimerManager(object): continue except asyncio.TimeoutError: pass + if len(self.timers) == 0: + continue _, callback = heapq.heappop(self.timers) - callback() + safe_callback(callback, "timer callback")