From 06ad7fefe178bcf7881f945d92fae3cc5e8fc082 Mon Sep 17 00:00:00 2001 From: counterweight Date: Tue, 23 Dec 2025 12:25:15 +0100 Subject: [PATCH] fix: improve error handling in admin trades fetch functions - Return errors from fetch functions instead of setting state directly - Clear error state before starting a new fetch - Combine errors when both upcoming and past trades fail to load - Handle fetch errors in handleAction as well --- frontend/app/admin/trades/page.tsx | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/frontend/app/admin/trades/page.tsx b/frontend/app/admin/trades/page.tsx index b75188b..70212b0 100644 --- a/frontend/app/admin/trades/page.tsx +++ b/frontend/app/admin/trades/page.tsx @@ -45,17 +45,18 @@ export default function AdminTradesPage() { const [statusFilter, setStatusFilter] = useState("all"); const [userSearch, setUserSearch] = useState(""); - const fetchUpcomingTrades = useCallback(async () => { + const fetchUpcomingTrades = useCallback(async (): Promise => { try { const data = await api.get("/api/admin/trades/upcoming"); setUpcomingTrades(data); + return null; } catch (err) { console.error("Failed to fetch upcoming trades:", err); - setError("Failed to load upcoming trades"); + return "Failed to load upcoming trades"; } }, []); - const fetchPastTrades = useCallback(async () => { + const fetchPastTrades = useCallback(async (): Promise => { try { let url = "/api/admin/trades/past"; const params = new URLSearchParams(); @@ -73,18 +74,28 @@ export default function AdminTradesPage() { const data = await api.get(url); setPastTrades(data); + return null; } catch (err) { console.error("Failed to fetch past trades:", err); - setError("Failed to load past trades"); + return "Failed to load past trades"; } }, [statusFilter, userSearch]); useEffect(() => { if (user && isAuthorized) { setIsLoadingTrades(true); - Promise.all([fetchUpcomingTrades(), fetchPastTrades()]).finally(() => { - setIsLoadingTrades(false); - }); + setError(null); + Promise.all([fetchUpcomingTrades(), fetchPastTrades()]) + .then(([upcomingErr, pastErr]) => { + // Combine errors if both failed + const errors = [upcomingErr, pastErr].filter(Boolean); + if (errors.length > 0) { + setError(errors.join("; ")); + } + }) + .finally(() => { + setIsLoadingTrades(false); + }); } }, [user, isAuthorized, fetchUpcomingTrades, fetchPastTrades]); @@ -99,7 +110,12 @@ export default function AdminTradesPage() { : `/api/admin/trades/${tradeId}/${action}`; await api.post(endpoint, {}); - await Promise.all([fetchUpcomingTrades(), fetchPastTrades()]); + // Refetch trades - errors from fetch are informational, not critical + const [upcomingErr, pastErr] = await Promise.all([fetchUpcomingTrades(), fetchPastTrades()]); + const fetchErrors = [upcomingErr, pastErr].filter(Boolean); + if (fetchErrors.length > 0) { + setError(fetchErrors.join("; ")); + } setConfirmAction(null); } catch (err) { setError(err instanceof Error ? err.message : `Failed to ${action} trade`);