Skip to content

Commit

Permalink
Implement graceful error handling at frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
ankith26 committed Dec 19, 2024
1 parent 2df2da2 commit 1265626
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 14 deletions.
13 changes: 8 additions & 5 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import Profs from './pages/Profs';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import FullPageLoader from './components/FullPageLoader';
import ErrorDialog from './components/ErrorDialog';

import './App.css'; // Import the global styles
import theme from './theme';

import { api, set_logout_callback } from './api';
import { api, set_logout_callback, set_errmsg_callback } from './api';

import { HOST_SUBPATH } from './constants';

Expand All @@ -33,6 +34,7 @@ function App() {
const [isLoggedIn, setIsLoggedIn] = useState(null);
const [courseList, setCourseList] = useState(null);
const [profList, setProfList] = useState(null);
const [errMsg, setErrMsg] = useState(null);

const logoutHandler = () => {
setIsLoggedIn(false);
Expand All @@ -42,6 +44,7 @@ function App() {

useEffect(() => {
set_logout_callback(logoutHandler);
set_errmsg_callback(setErrMsg);
const checkLoginAndFetchLists = async () => {
try {
const response_login = await api.get('/has_login');
Expand Down Expand Up @@ -76,17 +79,16 @@ function App() {
} else {
logoutHandler();
}
} catch (err) {
// TODO: display error in some popup
logoutHandler();
} catch (error) {
console.error('Error fetching login status and details:', error);
}
};

checkLoginAndFetchLists();
}, []);

if (isLoggedIn === null) {
return <FullPageLoader />;
return <><FullPageLoader /><ErrorDialog errorMessage={errMsg} /></>;
}

// make a Map out of profList data for efficient name lookup from email
Expand Down Expand Up @@ -131,6 +133,7 @@ function App() {
</Routes>
</Box>
<Footer />
<ErrorDialog errorMessage={errMsg} />
</Box>
</Router>
</ThemeProvider>
Expand Down
49 changes: 43 additions & 6 deletions frontend/src/api.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,53 @@ import { HOST_SUBPATH } from './constants';

const API_PREFIX = `${HOST_SUBPATH}api`;

const api = axios.create({
baseURL: API_PREFIX,
withCredentials: true,
maxRedirects: 0,
});
const api = axios.create({ baseURL: API_PREFIX });

/* Error handling API */
let errMsgCallback = null;
const set_errmsg_callback = (callback) => {
errMsgCallback = callback;
};
const set_errmsg = (msg) => {
if (errMsgCallback) {
errMsgCallback(msg);
}
};
const clear_errmsg = () => {
set_errmsg(null);
};

/* Intercept all API errors, convert them to human readable format and handle it */
api.interceptors.response.use(
(response) => response, // Pass successful responses as-is
(error) => {
let err_msg = 'Unknown error';
if (error.response) {
const detail = error.response.data?.detail || error.response.data?.message;
let more_info = 'Not specified';
if (Array.isArray(detail)) {
more_info = detail.map((item) => item.msg || JSON.stringify(item)).join(', ');
} else if (typeof detail === 'string' && detail) {
more_info = detail;
}

err_msg = `Backend returned an error: [code ${error.response.status}] ${more_info}`;
} else if (error.request) {
err_msg = "Backend must be down or under maintenance, it did not respond.";
} else {
err_msg = `Could not setup backend request: ${error.message}`;
}

set_errmsg(err_msg);
return Promise.reject({ message: err_msg });
}
);

function prefix_api(str) {
return API_PREFIX + str;
}

/* Login/logout API wrappers */
let logoutCallback = null;

const set_logout_callback = (callback) => {
Expand All @@ -34,4 +71,4 @@ function do_logout() {
window.location.href = prefix_api('/logout');
}

export { api, do_login, do_logout, set_logout_callback };
export { api, do_login, do_logout, set_logout_callback, set_errmsg_callback, clear_errmsg };
29 changes: 29 additions & 0 deletions frontend/src/components/ErrorDialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button } from '@mui/material';
import { clear_errmsg } from '../api';

const ErrorDialog = ({ errorMessage }) => {
return (
<Dialog open={!!errorMessage} onClose={clear_errmsg}>
<DialogTitle>Error Occurred</DialogTitle>
<DialogContent>
<DialogContentText>
{errorMessage}
</DialogContentText>
<DialogContentText>
Reloading the site might be helpful.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={clear_errmsg} color="secondary">
Close
</Button>
<Button onClick={() => window.location.reload()} color="primary" autoFocus>
Reload
</Button>
</DialogActions>
</Dialog>
);
};

export default ErrorDialog;
1 change: 0 additions & 1 deletion frontend/src/components/Review.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const Review = ({ review, endpoint, onUpdate }) => {
await onUpdate();
setOpenDialog(false); // Close dialog after deletion
} catch (error) {
// TODO: convey message to frontend
console.error('Error deleting the review:', error);
}
};
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/ReviewBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const ReviewBox = ({ children, title, endpoint, initExpanded }) => {
cache.current[endpoint] = response.data;
setReviewsList(response.data);
} catch (error) {
// TODO: report error in frontend
console.error('Error during search:', error);
}
};
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/ReviewInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ const ReviewInput = ({ endpoint, onUpdate, hasReview }) => {
setMessage('');
await onUpdate();
} catch (error) {
// Handle error during API request
console.error(`Error: ${error.message}`);
} finally {
setIsSubmitting(false); // Reset submission state
Expand Down

0 comments on commit 1265626

Please sign in to comment.