From 239dbce647162b4dc2c3a55db0afa8034cb802a8 Mon Sep 17 00:00:00 2001 From: Strycher Date: Sun, 14 Jun 2026 06:02:28 -0400 Subject: [PATCH] fix(#22): BLE notify-stream onError + await reaction-path send BLE onValueReceived.listen had no onError, while USB (L1557) and TCP (L1669) both attach one that logs and gracefully disconnects; an error emission on the BLE notify stream was unhandled. Add a matching onError. Also await sendMessageWithRetry in the reaction branch of sendMessage -- the normal path already awaits it; the reaction path's unawaited call swallowed failures, contradicting its own 'same as normal messages' comment. Verified, not assumed: Gemini's 'disconnect() not try-caught' was a FALSE POSITIVE (already wrapped at L2484-2489); 'deleteAllPaths silent void' is a sync in-memory clear (no async failure path). flutter analyze clean; Gemini-reviewed with no critique of these two changes. Co-Authored-By: Claude Opus 4.8 --- lib/connector/meshcore_connector.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 7912962..34a4f80 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -2052,6 +2052,10 @@ class MeshCoreConnector extends ChangeNotifier { } _notifySubscription = _txCharacteristic!.onValueReceived.listen( _handleFrame, + onError: (error, stackTrace) { + _appDebugLogService?.error('BLE transport error: $error', tag: 'BLE'); + unawaited(disconnect(manual: false)); + }, ); _setState(MeshCoreConnectionState.connected); @@ -2823,7 +2827,7 @@ class MeshCoreConnector extends ChangeNotifier { // Route through retry service (same as normal messages) // Don't use auto-rotation for reactions — just send directly if (_retryService != null) { - _retryService!.sendMessageWithRetry(contact: contact, text: text); + await _retryService!.sendMessageWithRetry(contact: contact, text: text); } else { final outboundText = prepareContactOutboundText(contact, text); await sendFrame(buildSendTextMsgFrame(contact.publicKey, outboundText));