Skip to content

Conversation

@zehata
Copy link
Contributor

@zehata zehata commented Dec 17, 2025

This is an extension to #4271, details of which I have copied over.
@leslieyip02 @jloh02 Patch for #4225, for the issue reported on the morning of 16 Dec by LH (https://t.me/NUSMods/13136)

Post-mortem

  1. When the app fetches the timetable modules, it populates the lesson indices which allows the migration of the module config to the new schema

    case SUCCESS_KEY(FETCH_MODULE):
    return {
    ...state,
    modules: {
    ...state.modules,
    [action.payload.moduleCode]: {
    ...action.payload,
    timestamp: Date.now(),
    semesterData: map(action.payload.semesterData, (semesterData) => ({
    ...semesterData,
    timetable: map(semesterData.timetable, (lesson, lessonIndex) => ({
    ...lesson,
    lessonIndex,
    })),

  2. The issue was caused by

    function fetchTimetableModulesImpl(timetable: SemTimetableConfig, semester: Semester) {
    dispatch(fetchTimetableModulesAction([timetable]))
    .then(() => dispatch(validateTimetable(semester)))

    calling
    export function validateTimetable(semester: Semester) {
    return (dispatch: Dispatch, getState: GetState) => {
    const { timetables, moduleBank } = getState();
    const { lessons, ta, alreadyMigrated } = migrateTimetableConfigs(
    timetables.lessons as TimetableConfig | TimetableConfigV1,
    timetables.ta as TaModulesMap | TaModulesMapV1,
    moduleBank.modules,
    );

When validateTimetable(1) is called when the app successfully fetches the module data for semester 1, it calls migrateTimetableConfigs which migrates the configs for all semesters, including semester 2. Since the request for semester 2 has not returned, the lesson indices has not been populated for semester 2 (see point 1). Trying to migrate the config for semester 2 will thus fail.

Fix

This patch fixes this issue by removing the migrateTimetableConfigs function and instead migrates each semester's timetable config as data is fetched for each of the semester.

It adds checks to prevent overwriting the user's config if any error occurs during the migration process.

It also adds code to create a random config to overwrite malformed configs caused by the migration failure.

@vercel
Copy link

vercel bot commented Dec 17, 2025

@zehata is attempting to deploy a commit to the modsbot's projects Team on Vercel.

A member of the Team first needs to authorize it.

@zehata zehata changed the title Fix premature migration with recovery Patch for #4225, with additional checks to prevent overwriting user config if error encountered and allow recovery for malformed configs Dec 17, 2025
@codecov
Copy link

codecov bot commented Dec 17, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.62%. Comparing base (988c6fd) to head (2986fbe).
⚠️ Report is 153 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4272      +/-   ##
==========================================
+ Coverage   54.52%   56.62%   +2.10%     
==========================================
  Files         274      297      +23     
  Lines        6076     6924     +848     
  Branches     1455     1671     +216     
==========================================
+ Hits         3313     3921     +608     
- Misses       2763     3003     +240     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zehata zehata mentioned this pull request Dec 17, 2025
@zehata zehata marked this pull request as draft December 17, 2025 10:15
@zehata zehata marked this pull request as ready for review December 17, 2025 10:16
@vercel
Copy link

vercel bot commented Dec 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
nusmods-export Ready Ready Preview, Comment Dec 20, 2025 8:50pm
nusmods-website Ready Ready Preview, Comment Dec 20, 2025 8:50pm

@zehata
Copy link
Contributor Author

zehata commented Dec 21, 2025

Also, while doing testing, I realized that the error occurred before writing to state, so users' configs were actually not overwritten. Nonetheless, I think it would make more sense to add checks to explicitly ensure that users' configs are not overwritten when errors are encountered.

Comment on lines +242 to +244
} = await Promise.resolve(
migrateSemTimetableConfig(semTimetableConfig, taModulesConfig, getModuleSemesterTimetable),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Promise.resolve needed? I don't think migrateSemTimetableConfig is async.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I am using it to end validation early if an error occurs during migration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course there are other ways of achieving the same effect

Copy link
Member

@leslieyip02 leslieyip02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for the speedy fix!

@leslieyip02 leslieyip02 merged commit a6b983e into nusmodifications:master Dec 22, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants