fix(#430): fast-fail caplog control ops on RESP_CODE_ERR (Gemini review)

Gemini review finding (medium): _handleErrorFrame only failed the caplog
download on RESP_CODE_ERR; control ops (enable/disable/erase) also get
RESP_CODE_ERR when the device is busy (firmware rejects non-STATUS ops while a
stream is in flight), so their completers hung 5s then threw a misleading
TimeoutException. Now fail the pending ack/status completers fast with
CaplogBusyException. analyze clean; full suite 643 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix/395-dm-channel-send-wedge
Strycher 2 months ago
parent 1021f9770d
commit f56bbc4fdc

@ -4795,10 +4795,22 @@ class MeshCoreConnector extends ChangeNotifier {
// active. (#430)
if (_caplogAwaitingStart) {
_caplogAwaitingStart = false;
final caplog = _caplogCompleter;
if (caplog != null && !caplog.isCompleted) {
caplog.completeError(const CaplogBusyException());
}
final download = _caplogCompleter;
if (download != null && !download.isCompleted) {
download.completeError(const CaplogBusyException());
}
}
// Control ops (enable / disable / erase / status) are likewise rejected with
// RESP_CODE_ERR while a stream is in flight; fail their pending completers
// fast rather than hanging until the 5s timeout. A status poll swallows the
// error and retries, so this is safe even for an unrelated ERR. (#430)
final ack = _caplogAckCompleter;
if (ack != null && !ack.isCompleted) {
ack.completeError(const CaplogBusyException());
}
final status = _caplogStatusCompleter;
if (status != null && !status.isCompleted) {
status.completeError(const CaplogBusyException());
}
final errCode = frame.length > 1 ? frame[1] : -1;
_appDebugLogService?.warn(

Loading…
Cancel
Save

Powered by TurnKey Linux.