FIX: Better erro handling for refreshAllWalletTransactions

This commit is contained in:
Marcos Rodriguez Velez 2025-02-12 00:42:38 -04:00
parent e176783a3f
commit f229beb5e0

View file

@ -172,56 +172,71 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
} }
}, [walletsInitialized]); }, [walletsInitialized]);
// Add a refresh lock to prevent concurrent refreshes
const refreshingRef = useRef<boolean>(false);
const refreshAllWalletTransactions = useCallback( const refreshAllWalletTransactions = useCallback(
async (lastSnappedTo?: number, showUpdateStatusIndicator: boolean = true) => { async (lastSnappedTo?: number, showUpdateStatusIndicator: boolean = true) => {
if (refreshingRef.current) {
console.debug('[refreshAllWalletTransactions] Refresh already in progress');
return;
}
console.debug('[refreshAllWalletTransactions] Starting refreshAllWalletTransactions');
refreshingRef.current = true;
const TIMEOUT_DURATION = 30000; const TIMEOUT_DURATION = 30000;
const timeoutPromise = new Promise<never>((_resolve, reject) => const timeoutPromise = new Promise<never>((_resolve, reject) =>
setTimeout(() => { setTimeout(() => {
reject(new Error('refreshAllWalletTransactions: Timeout reached')); console.debug('[refreshAllWalletTransactions] Timeout reached');
reject(new Error('Timeout reached'));
}, TIMEOUT_DURATION), }, TIMEOUT_DURATION),
); );
const mainLogicPromise = new Promise<void>((resolve, reject) => { try {
InteractionManager.runAfterInteractions(async () => { if (showUpdateStatusIndicator) {
let noErr = true; console.debug('[refreshAllWalletTransactions] Setting wallet transaction status to ALL');
try { setWalletTransactionUpdateStatus(WalletTransactionsStatus.ALL);
await BlueElectrum.waitTillConnected(); }
if (showUpdateStatusIndicator) { console.debug('[refreshAllWalletTransactions] Waiting for connectivity...');
setWalletTransactionUpdateStatus(WalletTransactionsStatus.ALL); await BlueElectrum.waitTillConnected();
} console.debug('[refreshAllWalletTransactions] Connected to Electrum');
const paymentCodesStart = Date.now();
await BlueApp.fetchSenderPaymentCodes(lastSnappedTo);
const paymentCodesEnd = Date.now();
console.debug('fetch payment codes took', (paymentCodesEnd - paymentCodesStart) / 1000, 'sec');
// Restore fetch payment codes timing measurement
if (typeof BlueApp.fetchSenderPaymentCodes === 'function') {
const codesStart = Date.now();
console.debug('[refreshAllWalletTransactions] Fetching sender payment codes');
await BlueApp.fetchSenderPaymentCodes(lastSnappedTo);
const codesEnd = Date.now();
console.debug('[refreshAllWalletTransactions] fetch payment codes took', (codesEnd - codesStart) / 1000, 'sec');
} else {
console.warn('[refreshAllWalletTransactions] fetchSenderPaymentCodes is not available');
}
console.debug('[refreshAllWalletTransactions] Fetching wallet balances and transactions');
await Promise.race([
(async () => {
const balanceStart = Date.now(); const balanceStart = Date.now();
await BlueApp.fetchWalletBalances(lastSnappedTo); await BlueApp.fetchWalletBalances(lastSnappedTo);
const balanceEnd = Date.now(); const balanceEnd = Date.now();
console.debug('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec'); console.debug('[refreshAllWalletTransactions] fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
const start = Date.now(); const txStart = Date.now();
await BlueApp.fetchWalletTransactions(lastSnappedTo); await BlueApp.fetchWalletTransactions(lastSnappedTo);
const end = Date.now(); const txEnd = Date.now();
console.debug('fetch tx took', (end - start) / 1000, 'sec'); console.debug('[refreshAllWalletTransactions] fetch tx took', (txEnd - txStart) / 1000, 'sec');
} catch (err) {
noErr = false;
console.error(err);
reject(err);
} finally {
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
}
if (noErr) await saveToDisk();
resolve();
});
});
try { console.debug('[refreshAllWalletTransactions] Saving data to disk');
await Promise.race([mainLogicPromise, timeoutPromise]); await saveToDisk();
} catch (err) { })(),
console.error('Error in refreshAllWalletTransactions:', err);
timeoutPromise,
]);
console.debug('[refreshAllWalletTransactions] Refresh completed successfully');
} catch (error) {
console.error('[refreshAllWalletTransactions] Error in refreshAllWalletTransactions:', error);
} finally { } finally {
console.debug('[refreshAllWalletTransactions] Resetting wallet transaction status and refresh lock');
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE); setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
refreshingRef.current = false;
} }
}, },
[saveToDisk], [saveToDisk],
@ -234,24 +249,26 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
let noErr = true; let noErr = true;
try { try {
if (Date.now() - (_lastTimeTriedToRefetchWallet[walletID] || 0) < 5000) { if (Date.now() - (_lastTimeTriedToRefetchWallet[walletID] || 0) < 5000) {
console.debug('Re-fetch wallet happens too fast; NOP'); console.debug('[fetchAndSaveWalletTransactions] Re-fetch wallet happens too fast; NOP');
return; return;
} }
_lastTimeTriedToRefetchWallet[walletID] = Date.now(); _lastTimeTriedToRefetchWallet[walletID] = Date.now();
await BlueElectrum.waitTillConnected(); await BlueElectrum.waitTillConnected();
setWalletTransactionUpdateStatus(walletID); setWalletTransactionUpdateStatus(walletID);
const balanceStart = Date.now(); const balanceStart = Date.now();
await BlueApp.fetchWalletBalances(index); await BlueApp.fetchWalletBalances(index);
const balanceEnd = Date.now(); const balanceEnd = Date.now();
console.debug('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec'); console.debug('[fetchAndSaveWalletTransactions] fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
const start = Date.now();
const txStart = Date.now();
await BlueApp.fetchWalletTransactions(index); await BlueApp.fetchWalletTransactions(index);
const end = Date.now(); const txEnd = Date.now();
console.debug('fetch tx took', (end - start) / 1000, 'sec'); console.debug('[fetchAndSaveWalletTransactions] fetch tx took', (txEnd - txStart) / 1000, 'sec');
} catch (err) { } catch (err) {
noErr = false; noErr = false;
console.error(err); console.error('[fetchAndSaveWalletTransactions] Error:', err);
} finally { } finally {
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE); setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
} }