Skip to content

Commit

Permalink
fix: error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed Jun 19, 2024
1 parent e2ed3bc commit 2e676db
Show file tree
Hide file tree
Showing 20 changed files with 172 additions and 21 deletions.
16 changes: 13 additions & 3 deletions src/course-checklist/CourseChecklist.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import AriaLiveRegion from './AriaLiveRegion';
import { RequestStatus } from '../data/constants';
import ChecklistSection from './ChecklistSection';
import { fetchCourseLaunchQuery, fetchCourseBestPracticesQuery } from './data/thunks';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';
import getUpdateLinks from './utils';

const CourseChecklist = ({
Expand All @@ -36,10 +37,19 @@ const CourseChecklist = ({
bestPracticeData,
} = useSelector(state => state.courseChecklist);

const { bestPracticeChecklistLoadingStatus, launchChecklistLoadingStatus } = loadingStatus;
const { bestPracticeChecklistStatus, launchChecklistStatus } = loadingStatus;

const isCourseLaunchChecklistLoading = bestPracticeChecklistLoadingStatus === RequestStatus.IN_PROGRESS;
const isCourseBestPracticeChecklistLoading = launchChecklistLoadingStatus === RequestStatus.IN_PROGRESS;
const isCourseLaunchChecklistLoading = bestPracticeChecklistStatus === RequestStatus.IN_PROGRESS;
const isCourseBestPracticeChecklistLoading = launchChecklistStatus === RequestStatus.IN_PROGRESS;
const isLoadingDenied = launchChecklistStatus === RequestStatus.DENIED;

if (isLoadingDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

return (
<>
Expand Down
6 changes: 5 additions & 1 deletion src/course-checklist/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export function fetchCourseLaunchQuery({
dispatch(fetchLaunchChecklistSuccess({ data }));
dispatch(updateLaunchChecklistStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateLaunchChecklistStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLaunchChecklistStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLaunchChecklistStatus({ status: RequestStatus.FAILED }));
}
}
};
}
Expand Down
22 changes: 22 additions & 0 deletions src/course-outline/CourseOutline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const CourseOutline = ({ courseId }) => {
sectionsList,
isCustomRelativeDatesActive,
isLoading,
isLoadingDenied,
isReIndexShow,
showSuccessAlert,
isSectionsExpanded,
Expand Down Expand Up @@ -232,6 +233,27 @@ const CourseOutline = ({ courseId }) => {
);
}

if (isLoadingDenied) {
return (
<Container size="xl" className="px-4 mt-4">
<PageAlerts
courseId={courseId}
notificationDismissUrl={notificationDismissUrl}
handleDismissNotification={handleDismissNotification}
discussionsSettings={discussionsSettings}
discussionsIncontextFeedbackUrl={discussionsIncontextFeedbackUrl}
discussionsIncontextLearnmoreUrl={discussionsIncontextLearnmoreUrl}
deprecatedBlocksInfo={deprecatedBlocksInfo}
proctoringErrors={proctoringErrors}
mfeProctoredExamSettingsUrl={mfeProctoredExamSettingsUrl}
advanceSettingsUrl={advanceSettingsUrl}
savingStatus={savingStatus}
errors={errors}
/>
</Container>
);
}

return (
<>
<Helmet>
Expand Down
15 changes: 11 additions & 4 deletions src/course-outline/data/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,17 @@ export function fetchCourseOutlineIndexQuery(courseId) {

dispatch(updateOutlineIndexLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateOutlineIndexLoadingStatus({
status: RequestStatus.FAILED,
errors: getErrorDetails(error, false),
}));
if (error.response && error.response.status === 403) {
dispatch(updateOutlineIndexLoadingStatus({
status: RequestStatus.DENIED,
errors: getErrorDetails(error, false),
}));
} else {
dispatch(updateOutlineIndexLoadingStatus({
status: RequestStatus.FAILED,
errors: getErrorDetails(error, false),
}));
}
}
};
}
Expand Down
1 change: 1 addition & 0 deletions src/course-outline/hooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ const useCourseOutline = ({ courseId }) => {
sectionsList,
isCustomRelativeDatesActive,
isLoading: outlineIndexLoadingStatus === RequestStatus.IN_PROGRESS,
isLoadingDenied: outlineIndexLoadingStatus === RequestStatus.DENIED,
isReIndexShow: Boolean(reindexLink),
showSuccessAlert,
isDisabledReindexButton,
Expand Down
10 changes: 10 additions & 0 deletions src/course-team/CourseTeam.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import CourseTeamMember from './course-team-member/CourseTeamMember';
import InfoModal from './info-modal/InfoModal';
import { useCourseTeam } from './hooks';
import getPageHeadTitle from '../generic/utils';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';

const CourseTeam = ({ courseId }) => {
const intl = useIntl();
Expand All @@ -35,6 +36,7 @@ const CourseTeam = ({ courseId }) => {
courseTeamUsers,
currentUserEmail,
isLoading,
isLoadingDenied,
isSingleAdmin,
isFormVisible,
isQueryPending,
Expand All @@ -55,6 +57,14 @@ const CourseTeam = ({ courseId }) => {
handleInternetConnectionFailed,
} = useCourseTeam({ intl, courseId });

if (isLoadingDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

if (isLoading) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
Expand Down
6 changes: 5 additions & 1 deletion src/course-team/data/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export function fetchCourseTeamQuery(courseId) {
dispatch(updateLoadingCourseTeamStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
} catch (error) {
dispatch(updateLoadingCourseTeamStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingCourseTeamStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingCourseTeamStatus({ status: RequestStatus.FAILED }));
}
return false;
}
};
Expand Down
1 change: 1 addition & 0 deletions src/course-team/hooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const useCourseTeam = ({ courseId }) => {
courseTeamUsers,
currentUserEmail,
isLoading: loadingCourseTeamStatus === RequestStatus.IN_PROGRESS,
isLoadingDenied: loadingCourseTeamStatus === RequestStatus.DENIED,
isSingleAdmin,
isFormVisible,
isAllowActions,
Expand Down
10 changes: 10 additions & 0 deletions src/course-updates/CourseUpdates.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getProcessingNotification } from '../generic/processing-notification/da
import ProcessingNotification from '../generic/processing-notification';
import SubHeader from '../generic/sub-header/SubHeader';
import InternetConnectionAlert from '../generic/internet-connection-alert';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';
import { RequestStatus } from '../data/constants';
import CourseHandouts from './course-handouts/CourseHandouts';
import CourseUpdate from './course-update/CourseUpdate';
Expand Down Expand Up @@ -64,9 +65,18 @@ const CourseUpdates = ({ courseId }) => {
const errors = useSelector(getErrors);

const anyStatusFailed = matchesAnyStatus({ ...loadingStatuses, ...savingStatuses }, RequestStatus.FAILED);
const anyStatusDenied = matchesAnyStatus({ ...loadingStatuses, ...savingStatuses }, RequestStatus.DENIED);
const anyStatusInProgress = matchesAnyStatus({ ...loadingStatuses, ...savingStatuses }, RequestStatus.IN_PROGRESS);
const anyStatusPending = matchesAnyStatus({ ...loadingStatuses, ...savingStatuses }, RequestStatus.PENDING);

if (anyStatusDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

return (
<>
<Helmet>
Expand Down
30 changes: 22 additions & 8 deletions src/course-updates/data/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ export function fetchCourseUpdatesQuery(courseId) {
error: { loadingUpdates: false },
}));
} catch (error) {
dispatch(updateLoadingStatuses({
status: { fetchCourseUpdatesQuery: RequestStatus.FAILED },
error: { loadingUpdates: true },
}));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatuses({
status: { fetchCourseUpdatesQuery: RequestStatus.DENIED },
error: { loadingUpdates: true },
}));
} else {
dispatch(updateLoadingStatuses({
status: { fetchCourseUpdatesQuery: RequestStatus.FAILED },
error: { loadingUpdates: true },
}));
}
}
};
}
Expand Down Expand Up @@ -116,10 +123,17 @@ export function fetchCourseHandoutsQuery(courseId) {
error: { loadingHandouts: false },
}));
} catch (error) {
dispatch(updateLoadingStatuses({
status: { fetchCourseHandoutsQuery: RequestStatus.FAILED },
error: { loadingHandouts: true },
}));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatuses({
status: { fetchCourseHandoutsQuery: RequestStatus.DENIED },
error: { loadingHandouts: true },
}));
} else {
dispatch(updateLoadingStatuses({
status: { fetchCourseHandoutsQuery: RequestStatus.FAILED },
error: { loadingHandouts: true },
}));
}
}
};
}
Expand Down
10 changes: 10 additions & 0 deletions src/export-page/CourseExportPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getConfig } from '@edx/frontend-platform';
import { Helmet } from 'react-helmet';

import InternetConnectionAlert from '../generic/internet-connection-alert';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';
import SubHeader from '../generic/sub-header/SubHeader';
import { RequestStatus } from '../data/constants';
import { useModel } from '../generic/model-store';
Expand All @@ -37,6 +38,7 @@ const CourseExportPage = ({ intl, courseId }) => {
const cookies = new Cookies();
const isShowExportButton = !exportTriggered || errorMessage || currentStage === EXPORT_STAGES.SUCCESS;
const anyRequestFailed = savingStatus === RequestStatus.FAILED || loadingStatus === RequestStatus.FAILED;
const isLoadingDenied = loadingStatus === RequestStatus.DENIED;
const anyRequestInProgress = savingStatus === RequestStatus.PENDING || loadingStatus === RequestStatus.IN_PROGRESS;

useEffect(() => {
Expand All @@ -48,6 +50,14 @@ const CourseExportPage = ({ intl, courseId }) => {
}
}, []);

if (isLoadingDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

return (
<>
<Helmet>
Expand Down
6 changes: 5 additions & 1 deletion src/export-page/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ export function fetchExportStatus(courseId) {
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
} catch (error) {
dispatch(updateLoadingStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
return false;
}
};
Expand Down
10 changes: 10 additions & 0 deletions src/grading-settings/GradingSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import AlertMessage from '../generic/alert-message';
import { RequestStatus } from '../data/constants';
import InternetConnectionAlert from '../generic/internet-connection-alert';
import SubHeader from '../generic/sub-header/SubHeader';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';
import SectionSubHeader from '../generic/section-sub-header';
import { STATEFUL_BUTTON_STATES } from '../constants';
import {
Expand All @@ -37,6 +38,7 @@ const GradingSettings = ({ intl, courseId }) => {
const courseAssignmentLists = useSelector(getCourseAssignmentLists);
const savingStatus = useSelector(getSavingStatus);
const loadingStatus = useSelector(getLoadingStatus);
const isLoadingDenied = loadingStatus === RequestStatus.DENIED;
const [showSuccessAlert, setShowSuccessAlert] = useState(false);
const dispatch = useDispatch();
const isLoading = loadingStatus === RequestStatus.IN_PROGRESS;
Expand Down Expand Up @@ -83,6 +85,14 @@ const GradingSettings = ({ intl, courseId }) => {
dispatch(fetchCourseSettingsQuery(courseId));
}, [courseId]);

if (isLoadingDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

if (isLoading) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
Expand Down
12 changes: 10 additions & 2 deletions src/grading-settings/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ export function fetchGradingSettings(courseId) {
dispatch(fetchGradingSettingsSuccess(settingValues));
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateLoadingStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
}
};
}
Expand Down Expand Up @@ -48,7 +52,11 @@ export function fetchCourseSettingsQuery(courseId) {
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
} catch (error) {
dispatch(updateLoadingStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
return false;
}
};
Expand Down
6 changes: 5 additions & 1 deletion src/group-configurations/data/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ export function fetchGroupConfigurationsQuery(courseId) {
dispatch(fetchGroupConfigurations({ groupConfigurations }));
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateLoadingStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus({ status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
}
};
}
Expand Down
1 change: 1 addition & 0 deletions src/group-configurations/hooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const useGroupConfigurations = (courseId) => {

return {
isLoading: loadingStatus === RequestStatus.IN_PROGRESS,
isLoadingDenied: loadingStatus === RequestStatus.DENIED,
savingStatus,
contentGroupActions,
experimentConfigurationActions,
Expand Down
10 changes: 10 additions & 0 deletions src/group-configurations/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import ExperimentConfigurationsSection from './experiment-configurations-section
import EnrollmentTrackGroupsSection from './enrollment-track-groups-section';
import GroupConfigurationSidebar from './group-configuration-sidebar';
import { useGroupConfigurations } from './hooks';
import ConnectionErrorAlert from '../generic/ConnectionErrorAlert';

const GroupConfigurations = ({ courseId }) => {
const { formatMessage } = useIntl();
Expand All @@ -34,13 +35,22 @@ const GroupConfigurations = ({ courseId }) => {
shouldShowExperimentGroups,
experimentGroupConfigurations,
},
isLoadingDenied,
} = useGroupConfigurations(courseId);

document.title = getPageHeadTitle(
courseDetails?.name,
formatMessage(messages.headingTitle),
);

if (isLoadingDenied) {
return (
<Container size="xl" className="course-unit px-4 mt-4">
<ConnectionErrorAlert />
</Container>
);
}

if (isLoading) {
return (
<Row className="m-0 mt-4 justify-content-center">
Expand Down
Loading

0 comments on commit 2e676db

Please sign in to comment.