aioble: Use DeviceDisconnectedError for disconnected guards.#472
Open
andrewleech wants to merge 2 commits intomicropython:masterfrom
Open
aioble: Use DeviceDisconnectedError for disconnected guards.#472andrewleech wants to merge 2 commits intomicropython:masterfrom
andrewleech wants to merge 2 commits intomicropython:masterfrom
Conversation
6fc995d to
6b7d13a
Compare
6b7d13a to
2117b6f
Compare
2117b6f to
cbe8041
Compare
cbe8041 to
c491981
Compare
7513416 to
021db78
Compare
Replace ValueError("Not connected") with DeviceDisconnectedError in
the is_connected() guards in L2CAPChannel.__init__,
DeviceConnection.exchange_mtu, and Characteristic.indicate. Callers
already catch DeviceDisconnectedError for disconnect handling; the
ValueError was not semantically correct and required string matching
to distinguish from other ValueErrors.
Also make L2CAPDisconnectedError a subclass of DeviceDisconnectedError
so that mid-operation L2CAP disconnections are caught by the same
handler (e.g. in the l2cap_file_server example).
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
021db78 to
a51c737
Compare
When the BLE peer disconnects during an L2CAP transfer, ble.l2cap_send(), ble.l2cap_recvinto(), and ble.l2cap_disconnect() raise OSError with errno EINVAL because the connection handle or CID is no longer valid. Callers catch L2CAPDisconnectedError (now a DeviceDisconnectedError subclass) for clean disconnect handling, but the raw OSError was not being converted — it fell through to generic exception handlers. Wrap all three call sites: - send(): catch OSError EINVAL, raise L2CAPDisconnectedError - recvinto(): catch OSError EINVAL, raise L2CAPDisconnectedError - disconnect(): catch OSError EINVAL, set _cid = None, return cleanly
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.
Summary
When a BLE peer disconnects during L2CAP operations, callers get a mix of
ValueError("Not connected"), bareL2CAPDisconnectedError(Exception), andOSError: [Errno 22] EINVALdepending on exactly which code path detects the disconnection first. Application code that catchesDeviceDisconnectedErrorfor clean disconnect handling (as thel2cap_file_serverexample does) misses all three.This PR unifies the disconnect signalling:
L2CAPDisconnectedErrorbecomes a subclass ofDeviceDisconnectedError, soexcept DeviceDisconnectedErrorcatches mid-operation L2CAP disconnections.ValueError("Not connected")guards inL2CAPChannel.__init__,DeviceConnection.exchange_mtu, andCharacteristic.indicateare replaced with the appropriateDeviceDisconnectedError(or subclass).OSError(EINVAL)from the low-levelble.l2cap_send(),ble.l2cap_recvinto(), andble.l2cap_disconnect()calls is caught and converted toL2CAPDisconnectedError. The BLE stack returns EINVAL when the connection handle or CID is no longer valid — semantically identical to a disconnection but previously not converted.disconnect()additionally sets_cid = Noneand returns cleanly since the channel is already gone.Testing
Tested on STM32WB55 with an OTS (Object Transfer Service) file transfer interrupted by client disconnect. Before: three
OSError: [Errno 22] EINVALERROR tracebacks per disconnect cycle. After: single INFO log "Transfer incomplete due to client disconnect".Trade-offs and Alternatives
Could catch all
OSErrorrather than checkingerrno == EINVALspecifically, but EINVAL is the only errno observed for this failure mode and catching broadly could mask real errors (e.g.ENOMEM).