From 9c4ade72376b2ccd5cc4f91e94a96653cfaf3d45 Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Fri, 17 Jul 2026 20:11:52 -0300 Subject: [PATCH] fix(wallet): surface background sync failures --- apps/shared/wallet/qml/WalletControl.qml | 22 ++++++++++++++++++ .../wallet/tests/qml/tst_WalletControl.qml | 23 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/shared/wallet/qml/WalletControl.qml b/apps/shared/wallet/qml/WalletControl.qml index 687de84..54d72a2 100644 --- a/apps/shared/wallet/qml/WalletControl.qml +++ b/apps/shared/wallet/qml/WalletControl.qml @@ -14,6 +14,7 @@ Item { property real viewportWidth: width property int selectedIndex: 0 property bool busy: false + property string handledSyncError: "" readonly property bool connected: root.wallet !== null && root.wallet.isWalletOpen readonly property string syncStatus: root.wallet @@ -74,6 +75,19 @@ Item { messageDialog.open() } + function handleSyncFailure() { + if (!root.wallet || root.syncStatus !== "error") { + root.handledSyncError = "" + return + } + const error = String(root.wallet.walletSyncError || "") + if (error.length === 0 || error === root.handledSyncError) + return + root.handledSyncError = error + root.busy = false + root.showError(qsTr("Wallet synchronization failed: %1").arg(error)) + } + function openWallet() { if (!root.wallet || root.busy) return @@ -116,6 +130,14 @@ Item { function onRowsRemoved() { root.clampSelection() } } + Connections { + target: root.wallet + ignoreUnknownSignals: true + + function onWalletSyncStatusChanged() { root.handleSyncFailure() } + function onWalletSyncErrorChanged() { root.handleSyncFailure() } + } + onConnectedChanged: { if (!root.connected) { root.selectedIndex = 0 diff --git a/apps/shared/wallet/tests/qml/tst_WalletControl.qml b/apps/shared/wallet/tests/qml/tst_WalletControl.qml index 157a0bc..021a072 100644 --- a/apps/shared/wallet/tests/qml/tst_WalletControl.qml +++ b/apps/shared/wallet/tests/qml/tst_WalletControl.qml @@ -14,6 +14,9 @@ Item { property bool isWalletOpen: false property bool walletExists: true property string walletHome: "/wallet" + property string walletSyncStatus: "closed" + property string walletSyncError: "" + property bool deferOpen: false property int openCalls: 0 property int createCalls: 0 property int publicAccountCalls: 0 @@ -22,7 +25,12 @@ Item { function openExisting() { openCalls++ - isWalletOpen = true + if (deferOpen) { + walletSyncStatus = "opening" + } else { + isWalletOpen = true + walletSyncStatus = "ready" + } return true } @@ -133,6 +141,19 @@ Item { tryCompare(fixture.control, "connected", true) } + function test_surfacesDeferredOpenFailure() { + const fixture = createControl({ walletExists: true, deferOpen: true }, []) + mouseClick(findChild(fixture.control, "walletConnectButton")) + compare(fixture.backend.openCalls, 1) + compare(fixture.control.syncStatus, "opening") + + fixture.backend.walletSyncStatus = "error" + fixture.backend.walletSyncError = "open_failed" + const dialog = findChild(fixture.control, "walletMessageDialog") + tryCompare(dialog, "opened", true) + verify(dialog.message.includes("open_failed")) + } + function test_requiresSeedBackupAcknowledgement() { const fixture = createControl({ walletExists: false }, []) mouseClick(findChild(fixture.control, "walletConnectButton"))