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.
This commit is contained in:
M3gA-Mind
2026-02-23 18:36:46 +05:30
parent 2bfdfbf6fd
commit 138983acdf
2 changed files with 51 additions and 18 deletions
+2 -1
View File
@@ -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}`);
+49 -17
View File
@@ -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 };