From dbe80811c35b7588161e368268288f6b6625f78f Mon Sep 17 00:00:00 2001 From: abose Date: Fri, 28 Aug 2026 00:57:10 +0530 Subject: [PATCH] fix: do not report a half finished migration as complete Cutting the bridge mid transfer produced "Migration complete", listed the 816 files that failed as a footnote, and set the done flag. Eight of 824 files had copied, the user was told it succeeded, and the automatic path would never try again. The cause is that per file errors are caught inside the loop so one unreadable file cannot kill the whole run. A bridge that dies therefore looks like 800 separate file failures rather than one crash, so the interrupted path never fired, which is the exact case it was written for. Only a clean run now records the done flag; anything less stays retryable and is reported as a failure, with the count missing and either the retry promise or the Help menu entry to use. The dialogs also said too little. "All done." left the user asking what was done, and "did not finish" did not say how far it got. Success now names what came across and where from, as a list of projects, extensions and settings with a file total. Failures lead with how many of how many files copied, and state that what did copy has been kept. Recent projects came across unusable. The list is absolute paths, and three kinds were broken on arrival: /mnt entries are File System Access mounts whose handles are origin bound and were never migrated, anything that failed to copy is not there either, and the same project could appear twice because ProjectManager hands out a trailing slash while RecentProjects stores none, so the two spellings did not compare equal and one of them failed to open. Entries are now normalised, filtered against what is actually on disk, and merged with the list this origin already had rather than replacing it. The task list also opens itself when the transfer starts. Nothing else announces the migration now that there is no dialog up front, so without it a user looking elsewhere never learns why the app is busy. --- .../MigrateAssist/migrator.js | 207 +++++++++++++++--- src/nls/root/strings.js | 19 +- src/styles/Extn-MigrateAssist.less | 15 -- 3 files changed, 184 insertions(+), 57 deletions(-) diff --git a/src/extensionsIntegrated/MigrateAssist/migrator.js b/src/extensionsIntegrated/MigrateAssist/migrator.js index 565fc33fab..6555386e79 100644 --- a/src/extensionsIntegrated/MigrateAssist/migrator.js +++ b/src/extensionsIntegrated/MigrateAssist/migrator.js @@ -42,6 +42,7 @@ define(function (require, exports, module) { TaskManager = require("features/TaskManager"), PreferencesManager = require("preferences/PreferencesManager"), CommandManager = require("command/CommandManager"), + FileUtils = require("file/FileUtils"), Commands = require("command/Commands"), Constants = require("./constants"); @@ -195,6 +196,16 @@ define(function (require, exports, module) { Strings.MIGRATE_PROGRESS_TITLE, StringUtils.format(Strings.MIGRATE_PROGRESS_STATUS, 0, totalFiles), ``); + + // Open the task list rather than leaving the copy behind a click. Nothing else announces the + // migration now that there is no dialog up front, so without this a user who happens to be + // looking elsewhere never learns why the app is busy. + // Guarded because show() toggles the dropdown: firing it while one is already open would + // close that instead. TaskManager closes this itself once the last task finishes. + if (!$(".dropdown-menu:visible").length) { + task.show(); + } + return { update: function (done) { task.setProgressPercent(Math.round((done / totalFiles) * 100)); @@ -219,9 +230,8 @@ define(function (require, exports, module) { * it finished would undo the point of moving progress out of a dialog in the first place. */ /** - * Errors are the one thing that earns an interruption here. Everything else rides on the status - * bar task: if that is already telling the user what is happening, a dialog repeating it is just - * another click for them. + * Nothing interrupts while the transfer is running: the status bar task carries that. Dialogs + * are reserved for the two moments the user has to act on, finishing and failing. */ function _errorDialog(title, message) { Dialogs.showModalDialog(DefaultDialogs.DIALOG_ID_ERROR, title, message); @@ -246,23 +256,76 @@ define(function (require, exports, module) { + StringUtils.format(Strings.CMD_MIGRATE_DATA, Constants.getLegacyDomainName()); } - function _showCompletion(migratedFiles, failed) { - const $actions = $("
").addClass("migrate-assist-toast-actions"); - const $reload = $("