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.
This commit is contained in:
M3gA-Mind
2026-02-23 17:52:56 +05:30
parent 23d21667e2
commit 2bfdfbf6fd
4 changed files with 33 additions and 17 deletions
+13
View File
@@ -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);
@@ -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')
}>
<div className="grid gap-6 lg:grid-cols-2">
<InputGroup
@@ -680,9 +680,9 @@ const TauriCommandsPanel = () => {
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')
}>
<div className="grid gap-8 lg:grid-cols-2">
<InputGroup
@@ -861,9 +861,9 @@ const TauriCommandsPanel = () => {
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')
}>
<div className="grid gap-8 lg:grid-cols-2">
<InputGroup title="Diagnostics" description="System health checks and model probing">
+7 -4
View File
@@ -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.');
+2 -2
View File
@@ -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) {