chore(runway): cherry-pick fix: improve Ledger error handling for disconnect, retry, and pagination cp-7.77.0#30190
Merged
Conversation
…connect, retry, and pagination cp-7.77.0 (#28515) ## **Description** Fixes multiple issues with Ledger hardware wallet error handling that caused confusing error dialogs when the device was disconnected, the Ethereum app was closed, or blind signing was disabled: 1. **Stale BLE transport cleanup** — `#closeTransport` now forces BLE disconnection even when the transport object is already null but a device ID remains, preventing the OS from keeping a stale connection that blocks reconnection. 2. **Broader transient error detection** — `#isTransientBleError` now falls back to message-based matching (e.g. "disconnected", "bluetooth", "gatt") for BLE errors that use generic `Error` names after a device power-cycle. 3. **Wrong-app command failure cleanup** — `#handleWrongApp` now closes the transport when `openEthereumAppOnLedger` or `closeRunningAppOnLedger` fails, preventing stale connections. 4. **Pagination device readiness** — `nextPage`/`prevPage` in `LedgerSelectAccount` now call `ensureDeviceReady` before fetching accounts, and only dismiss the blocking modal if it was actually shown (via a `modalShown` flag). 5. **Disconnect error classification** — `getLedgerAccountsByOperation` now detects disconnect errors and throws a user-friendly "device got disconnected" message instead of a generic error. 6. **Gitignore updates** — Added `.cursor/hooks/state/` to `.gitignore` to prevent Cursor IDE state files from being committed. ## **Changelog** CHANGELOG entry: Fixed Ledger hardware wallet error handling to properly recover from disconnects, app switching failures, and pagination errors ## **Related issues** Fixes: #28272 ## **Manual testing steps** ```gherkin Feature: Ledger error handling on disconnect Scenario: User disconnects Ledger during account pagination Given the user has connected a Ledger device via Bluetooth And the Ledger Select Account screen is displayed When the user disconnects the Ledger device And the user taps Next Page Then the app should prompt the user to reconnect instead of showing a generic error Scenario: User switches apps on Ledger during operation Given the user has connected a Ledger device with the Ethereum app open When the user switches to a different app on the Ledger And an operation is attempted Then the app should detect the transient BLE error and retry the connection Scenario: Ledger is powered off during account fetch Given the user has connected a Ledger device via Bluetooth And the Ledger Select Account screen is displayed When the user powers off the Ledger device And the user taps Next Page or Previous Page Then the app should show a disconnect-specific error message And the blocking modal should not be incorrectly dismissed ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes touch Ledger BLE transport cleanup/retry logic and account-pagination readiness gating, which can affect hardware-wallet connection stability and user flows. Risk is mitigated by expanded unit test coverage across adapter, error parsing, and UI pagination cases. > > **Overview** > Improves Ledger Bluetooth robustness by forcing BLE cleanup even when the transport object is already cleared, and by expanding transient disconnect detection to include message-based matches; it also closes the transport when app-switch commands fail to avoid stale connections. > > Updates `LedgerSelectAccount` pagination (`nextPage`/`prevPage`) to call `ensureDeviceReady` before fetching pages and to only dismiss the blocking modal if it was shown, preventing unnecessary modal flicker and avoiding pagination attempts when the device isn’t ready. > > Enhances Ledger error classification by treating disconnect-like failures in `getLedgerAccountsByOperation` as a user-facing “disconnected” error, and broadens `parseErrorByType` to handle non-`Error` objects with Ledger-shaped `name`/`statusCode`; adds/updates unit tests across these scenarios. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5e139f5. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Xiaoming Wang <dawnseeker8@users.noreply.github.com> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## release/7.77.0 #30190 +/- ##
=================================================
Coverage ? 81.54%
=================================================
Files ? 5332
Lines ? 141643
Branches ? 32298
=================================================
Hits ? 115504
Misses ? 18240
Partials ? 7899 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - PR targets a release branch (release/*) All E2E tests pre-selected. |
|
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.



Description
Fixes multiple issues with Ledger hardware wallet error handling that
caused confusing error dialogs when the device was disconnected, the
Ethereum app was closed, or blind signing was disabled:
#closeTransportnow forces BLEdisconnection even when the transport object is already null but a
device ID remains, preventing the OS from keeping a stale connection
that blocks reconnection.
#isTransientBleErrornowfalls back to message-based matching (e.g. "disconnected", "bluetooth",
"gatt") for BLE errors that use generic
Errornames after a devicepower-cycle.
#handleWrongAppnow closesthe transport when
openEthereumAppOnLedgerorcloseRunningAppOnLedgerfails, preventing stale connections.nextPage/prevPageinLedgerSelectAccountnow callensureDeviceReadybefore fetchingaccounts, and only dismiss the blocking modal if it was actually shown
(via a
modalShownflag).getLedgerAccountsByOperationnow detects disconnect errors and throws a user-friendly "device got
disconnected" message instead of a generic error.
.cursor/hooks/state/to.gitignoreto prevent Cursor IDE state files from being committed.
Changelog
CHANGELOG entry: Fixed Ledger hardware wallet error handling to properly
recover from disconnects, app switching failures, and pagination errors
Related issues
Fixes: #28272
Manual testing steps
Screenshots/Recordings
Before
N/A
After
N/A
Pre-merge author checklist
Docs and MetaMask Mobile
Coding
Standards.
if applicable
guidelines).
Not required for external contributors.
Pre-merge reviewer checklist
app, test code being changed).
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Note
Medium Risk
Changes touch Ledger BLE transport cleanup/retry logic and
account-pagination readiness gating, which can affect hardware-wallet
connection stability and user flows. Risk is mitigated by expanded unit
test coverage across adapter, error parsing, and UI pagination cases.
Overview
Improves Ledger Bluetooth robustness by forcing BLE cleanup even when
the transport object is already cleared, and by expanding transient
disconnect detection to include message-based matches; it also closes
the transport when app-switch commands fail to avoid stale connections.
Updates
LedgerSelectAccountpagination (nextPage/prevPage) tocall
ensureDeviceReadybefore fetching pages and to only dismiss theblocking modal if it was shown, preventing unnecessary modal flicker and
avoiding pagination attempts when the device isn’t ready.
Enhances Ledger error classification by treating disconnect-like
failures in
getLedgerAccountsByOperationas a user-facing“disconnected” error, and broadens
parseErrorByTypeto handlenon-
Errorobjects with Ledger-shapedname/statusCode; adds/updatesunit tests across these scenarios.
Reviewed by Cursor Bugbot for commit
5e139f5. Bugbot is set up for automated
code reviews on this repo. Configure
here.
Co-authored-by: Cursor Agent cursoragent@cursor.com
Co-authored-by: Xiaoming Wang dawnseeker8@users.noreply.github.com
Co-authored-by: metamaskbot metamaskbot@users.noreply.github.com
Co-authored-by: Nico MASSART NicolasMassart@users.noreply.github.com dc9bd4f