G1: F06 — wrap handle_rx dispatch in catch-all try/except

Why: handle_rx is invoked from a detached task in MessageReader, so any
exception escaping its ~850-line if/elif dispatch is silently swallowed
by asyncio as "Task exception was never retrieved." The only crash
guard previously was a single try/except IndexError around the first
byte read; everything past line 73 was unguarded. This commit adds an
umbrella try: ... except Exception as e: around the entire dispatch
body that logs the exception class, message, raw frame hex, and full
traceback via logger.error. The umbrella neutralizes the crash surface
of F10, F11, N07, N08, R01, NEW-B, and NEW-C, which the next commits
will then fix individually now that they are observable.

Refs: Forensics report finding F06 (umbrella crash protection)
This commit is contained in:
Matthew Wolter
2026-04-11 18:06:53 -07:00
parent fbf84cbdac
commit d9197faf3a

View File

@@ -3,6 +3,7 @@ import json
import struct
import time
import io
import traceback
from typing import Any, Dict
from .events import Event, EventType, EventDispatcher, ErrorMessages
from .meshcore_parser import MeshcorePacketParser
@@ -69,6 +70,7 @@ class MessageReader:
except IndexError as e:
logger.warning(f"Received empty packet: {e}")
return
try:
logger.debug(f"Received data: {data.hex()}")
# Handle command responses
@@ -919,3 +921,11 @@ class MessageReader:
else:
logger.debug(f"Unhandled data received {data}")
logger.debug(f"Unhandled packet type: {packet_type_value}")
except Exception as e:
logger.error(
"handle_rx parse error: %s: %s | raw=%s\n%s",
type(e).__name__,
e,
data.hex(),
traceback.format_exc(),
)