From c2bdaa3c0de5247e848142e81e42be8b59966152 Mon Sep 17 00:00:00 2001 From: dlawler489 <104159223@student.swin.edu.au> Date: Tue, 5 May 2026 20:02:30 +1000 Subject: [PATCH] fix: enhance CSV import rate limiting and UI protection - Reduce batch size from 3 to 2 expenses per batch for more conservative processing - Increase delay between batches from 1.5s to 2s to prevent HTTP 429 errors - Add isProcessingExpenses state to prevent multiple simultaneous imports - Disable import buttons during expense processing for better UX - Ensure processing state is always cleared in finally block Resolves HTTP 429 rate limiting errors during bulk expense creation from CSV imports. --- client/src/pages/DataImport.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/client/src/pages/DataImport.tsx b/client/src/pages/DataImport.tsx index 14331da..18d9f34 100644 --- a/client/src/pages/DataImport.tsx +++ b/client/src/pages/DataImport.tsx @@ -54,6 +54,7 @@ export default function DataImport() { const [etsyFile, setEtsyFile] = useState(null); const [shippingFile, setShippingFile] = useState(null); const [isLoading, setIsLoading] = useState(false); + const [isProcessingExpenses, setIsProcessingExpenses] = useState(false); const [results, setResults] = useState(null); // PDF Import State @@ -117,6 +118,8 @@ export default function DataImport() { etsyFees: EtsyFeeRecord[] ) => { try { + setIsProcessingExpenses(true); + // Get existing expenses to avoid duplicates const existingExpensesRes = await api.get('/expenses?limit=1000'); const existingExpenses = existingExpensesRes.data.expenses || []; @@ -180,9 +183,9 @@ export default function DataImport() { let created = 0; let skippedDuplicates = 0; - // Process expenses with rate limiting (conservative approach to avoid 429 errors) - const BATCH_SIZE = 3; // Reduced from 5 to be more conservative - const DELAY_MS = 1500; // Increased delay to 1.5 seconds + // Process expenses with very conservative rate limiting to prevent 429 errors + const BATCH_SIZE = 2; // Further reduced to 2 expenses per batch + const DELAY_MS = 2000; // Increased to 2 seconds between batches const totalBatches = Math.ceil(expensesToCreate.length / BATCH_SIZE); console.log(`Creating ${expensesToCreate.length} expenses in ${totalBatches} batches to avoid rate limiting...`); @@ -249,6 +252,8 @@ export default function DataImport() { } catch (error) { console.error('Error creating expenses:', error); toast.error('Failed to create expenses from CSV data'); + } finally { + setIsProcessingExpenses(false); } }; @@ -838,10 +843,10 @@ export default function DataImport() {
@@ -973,7 +978,8 @@ export default function DataImport() {