From 0571bf34507cc0535df38df21700cf2d9384f1c9 Mon Sep 17 00:00:00 2001 From: Tudor Date: Mon, 2 Feb 2026 21:28:50 +0000 Subject: [PATCH] Add error handling and fallbacks for API failures - Add try-catch blocks to all page components - Provide empty data fallbacks when API calls fail - Use optional chaining for safer property access - Log errors for debugging Fixes 'Cannot read properties of undefined' errors. Co-Authored-By: Claude Sonnet 4.5 --- nextjs-app/app/compare/page.tsx | 60 +++++++++++++++++++------------ nextjs-app/app/page.tsx | 50 ++++++++++++++++---------- nextjs-app/app/rankings/page.tsx | 62 ++++++++++++++++++++------------ 3 files changed, 107 insertions(+), 65 deletions(-) diff --git a/nextjs-app/app/compare/page.tsx b/nextjs-app/app/compare/page.tsx index b6b1341..095fe88 100644 --- a/nextjs-app/app/compare/page.tsx +++ b/nextjs-app/app/compare/page.tsx @@ -29,29 +29,43 @@ export default async function ComparePage({ searchParams }: ComparePageProps) { const urns = urnsParam?.split(',').map(Number).filter(Boolean) || []; const selectedMetric = metricParam || 'rwm_expected_pct'; - // Fetch comparison data if URNs provided - let comparisonData = null; - if (urns.length > 0) { - try { - const response = await fetchComparison(urnsParam!); - comparisonData = response.comparison; - } catch (error) { - console.error('Failed to fetch comparison:', error); + try { + // Fetch comparison data if URNs provided + let comparisonData = null; + if (urns.length > 0) { + try { + const response = await fetchComparison(urnsParam!); + comparisonData = response.comparison; + } catch (error) { + console.error('Failed to fetch comparison:', error); + } } + + // Fetch available metrics + const metricsResponse = await fetchMetrics(); + + // Convert metrics object to array + const metricsArray = Object.values(metricsResponse?.metrics || {}); + + return ( + + ); + } catch (error) { + console.error('Error fetching data for compare page:', error); + + // Return error state with empty metrics + return ( + + ); } - - // Fetch available metrics - const metricsResponse = await fetchMetrics(); - - // Convert metrics object to array - const metricsArray = Object.values(metricsResponse.metrics); - - return ( - - ); } diff --git a/nextjs-app/app/page.tsx b/nextjs-app/app/page.tsx index 538633f..781a62c 100644 --- a/nextjs-app/app/page.tsx +++ b/nextjs-app/app/page.tsx @@ -30,24 +30,36 @@ export default async function HomePage({ searchParams }: HomePageProps) { const page = parseInt(searchParams.page || '1'); const radius = searchParams.radius ? parseInt(searchParams.radius) : undefined; - // Fetch data on server - const [schoolsData, filtersData] = await Promise.all([ - fetchSchools({ - search: searchParams.search, - local_authority: searchParams.local_authority, - school_type: searchParams.school_type, - postcode: searchParams.postcode, - radius, - page, - page_size: 50, - }), - fetchFilters(), - ]); + // Fetch data on server with error handling + try { + const [schoolsData, filtersData] = await Promise.all([ + fetchSchools({ + search: searchParams.search, + local_authority: searchParams.local_authority, + school_type: searchParams.school_type, + postcode: searchParams.postcode, + radius, + page, + page_size: 50, + }), + fetchFilters(), + ]); - return ( - - ); + return ( + + ); + } catch (error) { + console.error('Error fetching data for home page:', error); + + // Return error state with empty data + return ( + + ); + } } diff --git a/nextjs-app/app/rankings/page.tsx b/nextjs-app/app/rankings/page.tsx index af27c3b..e8f865a 100644 --- a/nextjs-app/app/rankings/page.tsx +++ b/nextjs-app/app/rankings/page.tsx @@ -30,29 +30,45 @@ export default async function RankingsPage({ searchParams }: RankingsPageProps) const metric = metricParam || 'rwm_expected_pct'; const year = yearParam ? parseInt(yearParam) : undefined; - // Fetch rankings data - const [rankingsResponse, filtersResponse, metricsResponse] = await Promise.all([ - fetchRankings({ - metric, - local_authority, - year, - limit: 100, - }), - fetchFilters(), - fetchMetrics(), - ]); + // Fetch rankings data with error handling + try { + const [rankingsResponse, filtersResponse, metricsResponse] = await Promise.all([ + fetchRankings({ + metric, + local_authority, + year, + limit: 100, + }), + fetchFilters(), + fetchMetrics(), + ]); - // Convert metrics object to array - const metricsArray = Object.values(metricsResponse.metrics); + // Convert metrics object to array + const metricsArray = Object.values(metricsResponse?.metrics || {}); - return ( - - ); + return ( + + ); + } catch (error) { + console.error('Error fetching data for rankings page:', error); + + // Return error state with empty data + return ( + + ); + } }