From 138983acdf7fc1990be8fef948412fb9097545c1 Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Mon, 23 Feb 2026 18:36:46 +0530 Subject: [PATCH] fix: improve balance parsing and error handling in WalletInfoSection - Updated balance parsing logic in `WalletInfoSection` to ensure that non-finite values default to zero. - Enhanced error handling in `desktopDeepLinkListener` by adding error reporting for invalid encryption keys and conversion failures, improving user feedback and debugging capabilities. --- src/components/WalletInfoSection.tsx | 3 +- src/utils/desktopDeepLinkListener.ts | 66 +++++++++++++++++++++------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/components/WalletInfoSection.tsx b/src/components/WalletInfoSection.tsx index c0735653d..273ad2830 100644 --- a/src/components/WalletInfoSection.tsx +++ b/src/components/WalletInfoSection.tsx @@ -113,7 +113,8 @@ export default function WalletInfoSection() { } const eth = balanceData.balance_eth ?? '0'; const symbol = balanceData.symbol ?? 'ETH'; - const value = parseFloat(eth); + const parsed = parseFloat(eth); + const value = Number.isFinite(parsed) ? parsed : 0; const display = value < 0.0001 ? '0' : value.toFixed(4); if (!cancelledRef.current) { setBalance(`${display} ${symbol}`); diff --git a/src/utils/desktopDeepLinkListener.ts b/src/utils/desktopDeepLinkListener.ts index 7b23c5127..acd27bd38 100644 --- a/src/utils/desktopDeepLinkListener.ts +++ b/src/utils/desktopDeepLinkListener.ts @@ -3,6 +3,7 @@ import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link'; import { skillManager } from '../lib/skills/manager'; import { consumeLoginToken, fetchIntegrationTokens } from '../services/api/authApi'; +import { buildManualSentryEvent, enqueueError } from '../services/errorReportQueue'; import { store } from '../store'; import { setToken } from '../store/authSlice'; import { setSkillState } from '../store/skillsSlice'; @@ -24,7 +25,9 @@ function getCurrentUserId(): string | null { const parts = token.split('.'); if (parts.length !== 3) return null; const payloadBase64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); - const payloadJson = atob(payloadBase64); + const padLen = (4 - (payloadBase64.length % 4)) % 4; + const padded = padLen ? payloadBase64 + '='.repeat(padLen) : payloadBase64; + const payloadJson = atob(padded); const payload = JSON.parse(payloadJson); return payload.tgUserId || payload.userId || payload.sub || null; } catch { @@ -137,10 +140,20 @@ const handleOAuthDeepLink = async (parsed: URL) => { const trimmedHex = encryptionKeyHex.trim().replace(/^0x/i, ''); if (!trimmedHex || trimmedHex.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(trimmedHex)) { - console.error( - '[DeepLink] Cannot fetch integration tokens: encryption key must be non-empty hex (even length, [0-9a-fA-F])', - { userId, encryptionKeyHex } - ); + const msg = + '[DeepLink] Cannot fetch integration tokens: encryption key must be non-empty hex (even length, [0-9a-fA-F])'; + console.error(msg, { userId, encryptionKeyHex }); + enqueueError({ + id: crypto.randomUUID(), + timestamp: Date.now(), + source: 'manual', + title: 'Deep link integration tokens: invalid encryption key', + message: msg, + sentryEvent: buildManualSentryEvent( + { type: 'DeepLinkIntegrationTokensInvalidKey', value: msg }, + { component: 'desktopDeepLinkListener', userId, encryptionKeyHex } + ), + }); return; } @@ -148,17 +161,39 @@ const handleOAuthDeepLink = async (parsed: URL) => { try { keyForBackend = hexToBase64(trimmedHex); } catch (e) { - console.error( - '[DeepLink] Cannot fetch integration tokens: encryption key conversion failed', - { userId, encryptionKeyHex, error: e } - ); + const msg = + '[DeepLink] Cannot fetch integration tokens: encryption key conversion failed'; + console.error(msg, { userId, encryptionKeyHex, error: e }); + const err = e instanceof Error ? e : new Error(String(e)); + enqueueError({ + id: crypto.randomUUID(), + timestamp: Date.now(), + source: 'manual', + title: 'Deep link integration tokens: encryption key conversion failed', + message: err.message, + sentryEvent: buildManualSentryEvent( + { type: 'DeepLinkIntegrationTokensHexToBase64Error', value: err.message }, + { component: 'desktopDeepLinkListener', userId, encryptionKeyHex } + ), + originalError: err, + }); return; } if (!keyForBackend) { - console.error( - '[DeepLink] Cannot fetch integration tokens: encryption key produced empty base64', - { userId, encryptionKeyHex } - ); + const msg = + '[DeepLink] Cannot fetch integration tokens: encryption key produced empty base64'; + console.error(msg, { userId, encryptionKeyHex }); + enqueueError({ + id: crypto.randomUUID(), + timestamp: Date.now(), + source: 'manual', + title: 'Deep link integration tokens: empty key for backend', + message: msg, + sentryEvent: buildManualSentryEvent( + { type: 'DeepLinkIntegrationTokensEmptyKey', value: msg }, + { component: 'desktopDeepLinkListener', userId, encryptionKeyHex } + ), + }); return; } @@ -189,10 +224,7 @@ const handleOAuthDeepLink = async (parsed: URL) => { let extraCredential: { accessToken?: string } | undefined; if (skillId === 'gmail') { try { - const decryptedJson = await decryptIntegrationTokens( - response.data.encrypted, - trimmedHex - ); + const decryptedJson = await decryptIntegrationTokens(response.data.encrypted, trimmedHex); const payload = JSON.parse(decryptedJson) as IntegrationTokensPayload; if (payload.accessToken) { extraCredential = { accessToken: payload.accessToken };