Guard against InvalidStateError from stale BLE notifications in DeviceReader._notification_handler - #78
Open
shbatm wants to merge 1 commit into
Open
Conversation
A BLE notification arriving after the pending response future is already done (resolved by an earlier notification, or cancelled by the asyncio.wait_for timeout in _async_send_command) called set_result on the done future, raising asyncio.InvalidStateError inside the notification task. Drop such late/duplicate notifications with a debug log instead. Fixes Patrick762#64 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GcnWB3thiiJUoaHHJDS9r5
Owner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #64
Problem
DeviceReader._notification_handlercallsself.notify_future.set_result(...)unconditionally. If the pending response future is already done — resolved by an earlier notification, or cancelled by the 5sasyncio.wait_fortimeout in_async_send_command— a late or duplicate BLE notification raisesasyncio.InvalidStateErrorinside the notification task, which surfaces as an unhandled task exception.Seen in the wild via the
hassio-bluetti-btcustom integration (v0.2.2, pinningbluetti-bt-lib==0.1.7) on Home Assistant / Python 3.14, flooding the logs:Same root cause as the traceback reported in #64 (line 280 in 0.1.6 is the same
set_resultcall).Fix
Guard the resolution with
notify_future.done()(which also covers cancellation) and drop the stale notification with a debug log so it stays diagnosable. The guard runs beforenotify_response.extend(data)so a late fragment can't mutate abytearrayresult already delivered to the waiter in_async_send_command.Dropping is safe: the first response wins, and the existing consumer-side timeout already handles genuinely missed responses.
Testing
test_notification_with_done_futurecovering both the duplicate-notification and cancelled-future (timeout) paths; it fails withInvalidStateErrorbefore the fix and passes after.Dockerfile.testpasses (67 tests acrosstests/,fields/,registers/,base_devices/,devices/).black --target-version py310(the remaining reformat hints indevice_reader.pyare on pre-existing lines, left untouched to keep the diff minimal).No version bump included — left to the maintainer since
setup.pytakes the version fromLIB_VERSIONat release time.🤖 Generated with Claude Code
https://claude.ai/code/session_01GcnWB3thiiJUoaHHJDS9r5