Repository navigation
Conversation
The central manager delegate dropped the error from DidFailToConnectPeripheral and DidDisconnectPeripheral. Connect then returned a zero Device with a nil error, and the first GATT call on it panicked. Send the error along with the peripheral and return it from Connect. Fall back to a generic error when CoreBluetooth gives none, which happens when a disconnect from an earlier connection reaches a pending Connect.
acouvreur
marked this pull request as ready for review
October 17, 2026 20:44
deadprogram
reviewed
Oct 27, 2026
deadprogram
left a comment
Member
There was a problem hiding this comment.
Thanks for this. The main fix is correct. Before this change Connect returned connectionError, which is nil unless the timeout fired.
Some points:
- When a stale disconnect gets to
Connectand it returns an error, thea.cm.Connect(prphs[0], nil)call is still pending in CoreBluetooth. If that attempt then succeeds,DidConnectPeripheralfinds no channel and ignores it. The OS link stays up and noDeviceowns it. Please calla.cm.CancelConnect(prphs[0])on this error path whenconnectionError == nil. - After this change, a stale disconnect still makes the new
Connectfail, so the caller must retry. This is better than a panic, but please say it in the PR description. - The
Resetcomment still has an em dash (Connect — closing). You change the next line, so please fix this one too.
Also please test on a Mac with the steps in the description before we merge.
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 #278.
On macOS,
Connectcould return a zeroDevicewith a nil error. The central manager delegate dropped the error fromDidFailToConnectPeripheralandDidDisconnectPeripheral, andConnectreturnedconnectionError, which is only set on its own timeout. The first GATT call on thatDevicethen panicked.This happens when you connect right after
Disconnect. The disconnect event of the old connection reaches the new pendingConnect, as described by jbanyer in the issue.The delegate now sends the error with the peripheral.
Connectreturns, in order, its own timeout error, the CoreBluetooth error, or a generic error when CoreBluetooth gives none. AConnectunblocked byAdapter.Resetalso returns an error now instead of a zeroDevice.How to verify
Not tested on hardware yet. On a Mac, with any BLE peripheral in range:
DiscoverServices, callDisconnect, then callConnectagain right away, as in the issue.Connectcan return a nil error andDiscoverServicespanics. With it,Connecteither succeeds or returns an error, and a retry connects.Connectreturnstimeout on Connect.timeout on Connecttimeout on ConnectReset