Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions app/views/install/installer/js/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,18 @@
}
}
}
if (action === 'next' && String(target) === '5' && typeof validateInstallRequest === 'function') {
const isValid = await validateInstallRequest();
if (!isValid) {
return;
if (action === 'next' && String(target) === '5') {
if (typeof validateInstallRequest === 'function') {
const isValid = await validateInstallRequest();
if (!isValid) {
return;
}
}
// Clear stale install data from previous runs so initStep5
// starts a fresh install instead of trying to resume.
const { clearInstallLock, clearInstallId } = window.InstallerStepsState || {};
clearInstallLock?.();
clearInstallId?.();
}
if (isInstallLocked() && Number(target) !== 5) {
requestStep(5, true);
Expand Down
32 changes: 24 additions & 8 deletions app/views/install/installer/js/modules/progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,8 @@
});
startSyncedSpinnerRotation(list);

notifyInstallComplete(activeInstall?.installId, sessionDetails).finally(() => {
const completeId = activeInstall?.installId || getStoredInstallId?.();
notifyInstallComplete(completeId, sessionDetails).finally(() => {
setTimeout(() => redirectToApp(protocol), TIMINGS?.redirectDelay ?? 0);
});
};
Expand Down Expand Up @@ -912,21 +913,28 @@
};

const isSnapshotTerminal = (snapshot) => {
if (!snapshot?.steps) return true;
if (!snapshot?.steps) return 'empty';
const stepEntries = Object.values(snapshot.steps);
if (stepEntries.length === 0) return true;
if (stepEntries.length === 0) return 'empty';
const hasError = stepEntries.some((s) => s.status === STATUS.ERROR);
if (hasError) return true;
if (hasError) return 'error';
const allCompleted = INSTALLATION_STEPS.every((step) => {
const detail = snapshot.steps[step.id];
return detail && detail.status === STATUS.COMPLETED;
});
return allCompleted;
if (allCompleted) return 'completed';
return false;
};

const resumeInstall = async (installId) => {
const snapshot = await fetchInstallStatus(installId);
if (!snapshot || isSnapshotTerminal(snapshot)) return false;
const terminal = isSnapshotTerminal(snapshot);
if (!snapshot || terminal) {
if (terminal === 'completed') {
return 'completed';
}
return false;
}
activeInstall = {
installId,
controller: new AbortController(),
Expand Down Expand Up @@ -1086,8 +1094,16 @@
const lock = getInstallLock?.();
const existingInstallId = lock?.installId || getStoredInstallId?.();
if (existingInstallId) {
resumeInstall(existingInstallId).then((resumed) => {
if (!resumed) {
resumeInstall(existingInstallId).then((result) => {
if (result === 'completed') {
// Install already finished — redirect to console
// instead of bouncing back to step 1.
stopSyncedSpinnerRotation();
setUnloadGuard(false);
clearInstallLock?.();
clearInstallId?.();
startSslCheck(null);
Comment on lines +1098 to +1105
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 notifyInstallComplete silently no-ops in the completed-reload path

clearInstallId?.() is called on line 1104 before startSslCheck(null) on line 1105. By the time showRedirectStep runs and evaluates activeInstall?.installId || getStoredInstallId?.(), both sources are nullactiveInstall was never set in this branch and the stored ID was just cleared. As a result, notifyInstallComplete is called with undefined and short-circuits immediately (if (!installId) return Promise.resolve()).

The redirect still happens correctly via .finally(), and since this path represents a reload of an already-completed install (no new session data to report), skipping the notification is arguably intentional. However, the getStoredInstallId?.() fallback added to showRedirectStep provides no benefit in this code path. A brief comment explaining the intentional skip would help future readers.

} else if (!result) {
recoverToLastStep();
}
});
Expand Down
Loading