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 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ export default async function ComparePage({ searchParams }: ComparePageProps) {
|
|||||||
const urns = urnsParam?.split(',').map(Number).filter(Boolean) || [];
|
const urns = urnsParam?.split(',').map(Number).filter(Boolean) || [];
|
||||||
const selectedMetric = metricParam || 'rwm_expected_pct';
|
const selectedMetric = metricParam || 'rwm_expected_pct';
|
||||||
|
|
||||||
|
try {
|
||||||
// Fetch comparison data if URNs provided
|
// Fetch comparison data if URNs provided
|
||||||
let comparisonData = null;
|
let comparisonData = null;
|
||||||
if (urns.length > 0) {
|
if (urns.length > 0) {
|
||||||
@@ -44,7 +45,7 @@ export default async function ComparePage({ searchParams }: ComparePageProps) {
|
|||||||
const metricsResponse = await fetchMetrics();
|
const metricsResponse = await fetchMetrics();
|
||||||
|
|
||||||
// Convert metrics object to array
|
// Convert metrics object to array
|
||||||
const metricsArray = Object.values(metricsResponse.metrics);
|
const metricsArray = Object.values(metricsResponse?.metrics || {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComparisonView
|
<ComparisonView
|
||||||
@@ -54,4 +55,17 @@ export default async function ComparePage({ searchParams }: ComparePageProps) {
|
|||||||
selectedMetric={selectedMetric}
|
selectedMetric={selectedMetric}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data for compare page:', error);
|
||||||
|
|
||||||
|
// Return error state with empty metrics
|
||||||
|
return (
|
||||||
|
<ComparisonView
|
||||||
|
initialData={null}
|
||||||
|
initialUrns={urns}
|
||||||
|
metrics={[]}
|
||||||
|
selectedMetric={selectedMetric}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ export default async function HomePage({ searchParams }: HomePageProps) {
|
|||||||
const page = parseInt(searchParams.page || '1');
|
const page = parseInt(searchParams.page || '1');
|
||||||
const radius = searchParams.radius ? parseInt(searchParams.radius) : undefined;
|
const radius = searchParams.radius ? parseInt(searchParams.radius) : undefined;
|
||||||
|
|
||||||
// Fetch data on server
|
// Fetch data on server with error handling
|
||||||
|
try {
|
||||||
const [schoolsData, filtersData] = await Promise.all([
|
const [schoolsData, filtersData] = await Promise.all([
|
||||||
fetchSchools({
|
fetchSchools({
|
||||||
search: searchParams.search,
|
search: searchParams.search,
|
||||||
@@ -47,7 +48,18 @@ export default async function HomePage({ searchParams }: HomePageProps) {
|
|||||||
return (
|
return (
|
||||||
<HomeView
|
<HomeView
|
||||||
initialSchools={schoolsData}
|
initialSchools={schoolsData}
|
||||||
filters={filtersData.filters}
|
filters={filtersData?.filters || { local_authorities: [], school_types: [], years: [] }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data for home page:', error);
|
||||||
|
|
||||||
|
// Return error state with empty data
|
||||||
|
return (
|
||||||
|
<HomeView
|
||||||
|
initialSchools={{ schools: [], pagination: { page: 1, page_size: 50, total: 0, pages: 0 } }}
|
||||||
|
filters={{ local_authorities: [], school_types: [], years: [] }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ export default async function RankingsPage({ searchParams }: RankingsPageProps)
|
|||||||
const metric = metricParam || 'rwm_expected_pct';
|
const metric = metricParam || 'rwm_expected_pct';
|
||||||
const year = yearParam ? parseInt(yearParam) : undefined;
|
const year = yearParam ? parseInt(yearParam) : undefined;
|
||||||
|
|
||||||
// Fetch rankings data
|
// Fetch rankings data with error handling
|
||||||
|
try {
|
||||||
const [rankingsResponse, filtersResponse, metricsResponse] = await Promise.all([
|
const [rankingsResponse, filtersResponse, metricsResponse] = await Promise.all([
|
||||||
fetchRankings({
|
fetchRankings({
|
||||||
metric,
|
metric,
|
||||||
@@ -43,16 +44,31 @@ export default async function RankingsPage({ searchParams }: RankingsPageProps)
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Convert metrics object to array
|
// Convert metrics object to array
|
||||||
const metricsArray = Object.values(metricsResponse.metrics);
|
const metricsArray = Object.values(metricsResponse?.metrics || {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RankingsView
|
<RankingsView
|
||||||
rankings={rankingsResponse.rankings}
|
rankings={rankingsResponse?.rankings || []}
|
||||||
filters={filtersResponse.filters}
|
filters={filtersResponse?.filters || { local_authorities: [], school_types: [], years: [] }}
|
||||||
metrics={metricsArray}
|
metrics={metricsArray}
|
||||||
selectedMetric={metric}
|
selectedMetric={metric}
|
||||||
selectedArea={local_authority}
|
selectedArea={local_authority}
|
||||||
selectedYear={year}
|
selectedYear={year}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data for rankings page:', error);
|
||||||
|
|
||||||
|
// Return error state with empty data
|
||||||
|
return (
|
||||||
|
<RankingsView
|
||||||
|
rankings={[]}
|
||||||
|
filters={{ local_authorities: [], school_types: [], years: [] }}
|
||||||
|
metrics={[]}
|
||||||
|
selectedMetric={metric}
|
||||||
|
selectedArea={local_authority}
|
||||||
|
selectedYear={year}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user