From 2bfdfbf6fdc89791446625f3bded46a1a4f14b24 Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Mon, 23 Feb 2026 17:52:56 +0530 Subject: [PATCH] feat: enhance error handling in WalletInfoSection and improve user feedback - Added error reporting functionality in `WalletInfoSection` to capture and enqueue errors when wallet info fails to load. - Updated `Mnemonic` component to handle user state more robustly, ensuring encryption key is only set if the user is loaded. - Refactored `TauriCommandsPanel` to improve string comparisons for loading states by converting to lowercase. - Adjusted deep link handling in `desktopDeepLinkListener` to use trimmed hex values for encryption key conversion. --- src/components/WalletInfoSection.tsx | 13 +++++++++++ .../settings/panels/TauriCommandsPanel.tsx | 22 +++++++++---------- src/pages/Mnemonic.tsx | 11 ++++++---- src/utils/desktopDeepLinkListener.ts | 4 ++-- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/components/WalletInfoSection.tsx b/src/components/WalletInfoSection.tsx index e722c2991..c0735653d 100644 --- a/src/components/WalletInfoSection.tsx +++ b/src/components/WalletInfoSection.tsx @@ -3,6 +3,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { useUser } from '../hooks/useUser'; import { useSkillConnectionStatus } from '../lib/skills/hooks'; import { skillManager } from '../lib/skills/manager'; +import { buildManualSentryEvent, enqueueError } from '../services/errorReportQueue'; import { useAppSelector } from '../store/hooks'; function truncateAddress(address: string): string { @@ -131,6 +132,18 @@ export default function WalletInfoSection() { return; } console.error('[WalletInfoSection] Failed to load wallet info:', e); + enqueueError({ + id: crypto.randomUUID(), + timestamp: Date.now(), + source: 'manual', + title: 'Failed to load wallet info', + message: e instanceof Error ? e.message : String(e), + sentryEvent: buildManualSentryEvent( + { type: 'WalletInfoLoadError', value: e instanceof Error ? e.message : String(e) }, + { component: 'WalletInfoSection' } + ), + originalError: e instanceof Error ? e : new Error(String(e)), + }); setError('Failed to load wallet info'); setBalance(null); setNetworkName(null); diff --git a/src/components/settings/panels/TauriCommandsPanel.tsx b/src/components/settings/panels/TauriCommandsPanel.tsx index 420deadc5..808ac2be2 100644 --- a/src/components/settings/panels/TauriCommandsPanel.tsx +++ b/src/components/settings/panels/TauriCommandsPanel.tsx @@ -37,8 +37,8 @@ import { runtimeEnableSkill, runtimeIsSkillEnabled, runtimeListSkills, - SkillSnapshot, - TunnelConfig, + type SkillSnapshot, + type TunnelConfig, } from '../../../utils/tauriCommands'; import SettingsHeader from '../components/SettingsHeader'; import { useSettingsNavigation } from '../hooks/useSettingsNavigation'; @@ -554,9 +554,9 @@ const TauriCommandsPanel = () => { defaultExpanded={!isCollapsed('security-data')} hasChanges={false} loading={ - operationLoading?.includes('Secret') || - operationLoading?.includes('Models') || - operationLoading?.includes('Integration') + operationLoading?.toLowerCase()?.includes('secret') || + operationLoading?.toLowerCase()?.includes('models') || + operationLoading?.toLowerCase()?.includes('integration') }>
{ defaultExpanded={!isCollapsed('network-infrastructure')} hasChanges={false} loading={ - operationLoading?.includes('Gateway') || - operationLoading?.includes('Tunnel') || - operationLoading?.includes('Memory') + operationLoading?.toLowerCase()?.includes('gateway') || + operationLoading?.toLowerCase()?.includes('tunnel') || + operationLoading?.toLowerCase()?.includes('memory') }>
{ defaultExpanded={!isCollapsed('development-operations')} hasChanges={false} loading={ - operationLoading?.includes('Doctor') || - operationLoading?.includes('Hardware') || - operationLoading?.includes('Migration') + operationLoading?.toLowerCase()?.includes('doctor') || + operationLoading?.toLowerCase()?.includes('hardware') || + operationLoading?.toLowerCase()?.includes('migration') }>
diff --git a/src/pages/Mnemonic.tsx b/src/pages/Mnemonic.tsx index e14fb6e27..8848c3cf0 100644 --- a/src/pages/Mnemonic.tsx +++ b/src/pages/Mnemonic.tsx @@ -150,11 +150,14 @@ const Mnemonic = () => { const aesKey = deriveAesKeyFromMnemonic(phraseToUse); const walletAddress = deriveEvmAddressFromMnemonic(phraseToUse); - if (user?._id) { - dispatch(setEncryptionKeyForUser({ userId: user._id, key: aesKey })); - await skillManager.setWalletAddress(walletAddress); + if (!user?._id) { + const msg = 'User not loaded. Please sign in again or refresh the page.'; + setError(msg); + console.error('[Mnemonic] Cannot save encryption key: user not loaded'); + return; } - + dispatch(setEncryptionKeyForUser({ userId: user._id, key: aesKey })); + await skillManager.setWalletAddress(walletAddress); navigate('/home'); } catch (e) { setError(e instanceof Error ? e.message : 'Something went wrong. Please try again.'); diff --git a/src/utils/desktopDeepLinkListener.ts b/src/utils/desktopDeepLinkListener.ts index aacdc7509..7b23c5127 100644 --- a/src/utils/desktopDeepLinkListener.ts +++ b/src/utils/desktopDeepLinkListener.ts @@ -146,7 +146,7 @@ const handleOAuthDeepLink = async (parsed: URL) => { let keyForBackend: string; try { - keyForBackend = hexToBase64(encryptionKeyHex); + keyForBackend = hexToBase64(trimmedHex); } catch (e) { console.error( '[DeepLink] Cannot fetch integration tokens: encryption key conversion failed', @@ -191,7 +191,7 @@ const handleOAuthDeepLink = async (parsed: URL) => { try { const decryptedJson = await decryptIntegrationTokens( response.data.encrypted, - encryptionKeyHex + trimmedHex ); const payload = JSON.parse(decryptedJson) as IntegrationTokensPayload; if (payload.accessToken) {