Skip to content

Commit e3d3829

Browse files
committed
feat: implement ErrorBoundary component for enhanced error handling in HomePage #deploy
1 parent 47c17ca commit e3d3829

2 files changed

Lines changed: 100 additions & 10 deletions

File tree

src/components/ErrorBoundary.jsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react'
2+
import { Switch } from '@headlessui/react'
3+
4+
class ErrorBoundary extends React.Component {
5+
constructor(props) {
6+
super(props)
7+
this.state = { hasError: false, error: null }
8+
}
9+
10+
static getDerivedStateFromError(error) {
11+
return { hasError: true, error }
12+
}
13+
14+
componentDidCatch(error, errorInfo) {
15+
console.error('ErrorBoundary caught an error:', error, errorInfo)
16+
}
17+
18+
render() {
19+
if (this.state.hasError) {
20+
return (
21+
<div className="my-2 rounded-md bg-red-50 p-4 dark:bg-red-900/20">
22+
<div className="flex flex-col items-center justify-center">
23+
<h3 className="mb-2 text-lg font-semibold text-red-800 dark:text-red-200">
24+
Unable to Load Data
25+
</h3>
26+
<p className="mb-4 text-center text-red-700 dark:text-red-300">
27+
{this.state.error?.message ||
28+
'An error occurred while loading the data. Please try switching semesters or try again.'}
29+
</p>
30+
<div className="flex flex-col items-center gap-4">
31+
<div className="flex items-center gap-2">
32+
<p className="text-sm font-semibold">Try switching semester:</p>
33+
<Switch
34+
checked={this.props.enabled}
35+
onChange={this.props.onToggle}
36+
className={`${
37+
this.props.enabled
38+
? 'bg-blue-600'
39+
: 'bg-white dark:bg-gray-500'
40+
} relative inline-flex h-6 w-11 items-center rounded-full`}
41+
>
42+
<span
43+
className={`${
44+
this.props.enabled ? 'translate-x-6' : 'translate-x-1'
45+
} inline-block h-4 w-4 transform rounded-full bg-gray-200 transition dark:bg-white`}
46+
/>
47+
</Switch>
48+
<span className="text-sm">
49+
{this.props.enabled ? 'Even' : 'Odd'} Sem
50+
</span>
51+
</div>
52+
<button
53+
onClick={this.props.onRetry}
54+
className="rounded bg-blue-600 px-4 py-2 font-semibold text-white hover:bg-blue-700"
55+
>
56+
Try Again
57+
</button>
58+
</div>
59+
</div>
60+
</div>
61+
)
62+
}
63+
64+
return this.props.children
65+
}
66+
}
67+
68+
export default ErrorBoundary

src/pages/minisis.jsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { BadgeCheck, Target, TrendingUp } from 'lucide-react'
2525
import { Switch } from '@headlessui/react'
2626
import AcademicHistory from '@/components/AcademicHistory'
2727
import LoginHistory from '@/components/LoginHistory'
28+
import ErrorBoundary from '@/components/ErrorBoundary'
2829

2930
if (!firebase.apps.length) {
3031
firebase.initializeApp(firebaseConfig)
@@ -747,18 +748,29 @@ function HomePage() {
747748
apiurl = 'https://reconnect-msrit.vercel.app/test'
748749
}
749750
const response = await fetch(apiurl)
750-
if (!response.ok) {
751-
if (response.status === 500) {
752-
const error = new Error(
753-
'Server error: This endpoint is currently inactive. Try switching the semester toggle to use a different endpoint.'
754-
)
755-
error.isEndpointError = true
756-
throw error
751+
let data;
752+
try {
753+
if (!response.ok) {
754+
if (response.status === 500) {
755+
const error = new Error(
756+
'Server error: This endpoint is currently inactive. Try switching the semester toggle to use a different endpoint.'
757+
)
758+
error.isEndpointError = true
759+
// Throw error to be caught by error boundary
760+
throw error
761+
}
762+
const resp = await response.json()
763+
throw new Error(resp.error || 'Failed to fetch data.')
757764
}
758-
const resp = await response.json()
759-
throw new Error(resp.error || 'Failed to fetch data.')
765+
data = await response.json()
766+
} catch (error) {
767+
// Set error state and clear data
768+
setStudentData(null)
769+
setError(error.message || 'An unexpected error occurred')
770+
setHasError(true)
771+
// Re-throw the error to be caught by error boundary
772+
throw error
760773
}
761-
const data = await response.json()
762774
localStorage.setItem('usn', currentUsn)
763775
localStorage.setItem('dob', currentDob)
764776
localStorage.setItem('studentData', JSON.stringify(data))
@@ -1068,6 +1080,15 @@ function HomePage() {
10681080
) : (
10691081
<section className="flex w-full items-center justify-center bg-indigo-50 pb-8 dark:bg-gray-900 sm:py-2">
10701082
<div className="max-w-3xl lg:mx-auto lg:w-full">
1083+
<ErrorBoundary
1084+
enabled={enabled}
1085+
onToggle={(value) => {
1086+
setEnabled(value)
1087+
localStorage.setItem('semesterToggle', value)
1088+
handleFetchData(usn, dob)
1089+
}}
1090+
onRetry={() => handleFetchData(usn, dob)}
1091+
>
10711092
{studentData && (
10721093
<>
10731094
<div className="my-2 rounded-md shadow-md dark:bg-gray-800">
@@ -1255,6 +1276,7 @@ function HomePage() {
12551276
)}
12561277
</>
12571278
)}
1279+
</ErrorBoundary>
12581280
<div className="mt-4 flex justify-center gap-4">
12591281
<button
12601282
onClick={handleReload}

0 commit comments

Comments
 (0)