Skip to content

Commit 9bfe9dd

Browse files
FrankLiu4138Copilot
andcommitted
Fix Java upgrade notification flow telemetry and activation check
Addresses three follow-up improvements from v0.27.5 telemetry analysis (#5979): 1. Add hasCVEIssue field to upgradeNotification.show event so the 6 (state x type) buckets can be split at the NOTIFY level. 2. Emit upgradeFlow.result success right after installExtension resolves on the outdated path (instead of only after reload acceptance, which was lost 81% of the time), wrap install in try/catch to label install-failed, and report reload acceptance as a separate reloadChoice event. 3. Replace the fixed setTimeout(2000) post-install activation wait with a 15s polling loop to fix the 41% false activation-timeout rate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4db30ab commit 9bfe9dd

2 files changed

Lines changed: 32 additions & 14 deletions

File tree

src/upgrade/display/notificationManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class NotificationManager implements IUpgradeIssuesRenderer {
9393
sendInfo(operationId, {
9494
operationName: "java.dependency.upgradeNotification.show",
9595
extensionState,
96+
hasCVEIssue: hasCVEIssue ? "true" : "false",
9697
});
9798

9899
const buttons = hasCVEIssue

src/upgrade/utility.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,36 +196,53 @@ export async function checkOrInstallAppModExtensionForUpgrade(
196196
return true;
197197
}
198198

199-
await commands.executeCommand("workbench.extensions.installExtension", ExtensionName.APP_MODERNIZATION_FOR_JAVA);
199+
try {
200+
await commands.executeCommand("workbench.extensions.installExtension", ExtensionName.APP_MODERNIZATION_FOR_JAVA);
201+
} catch (error) {
202+
sendInfo(operationId, {
203+
operationName: "java.dependency.upgradeFlow.result",
204+
upgradeFlowResult: "install-failed",
205+
error: error instanceof Error ? error.message : String(error),
206+
});
207+
return false;
208+
}
200209

201210
if (state === "outdated") {
211+
// Install completed — record success now; what the user does with the
212+
// reload prompt is a separate UX concern that can be lost to dismissal,
213+
// window close, or the reload itself swallowing telemetry.
214+
sendInfo(operationId, {
215+
operationName: "java.dependency.upgradeFlow.result",
216+
upgradeFlowResult: "proceeded",
217+
});
218+
202219
// Extension was updated (not freshly installed) — reload required
203220
const reload = await window.showInformationMessage(
204221
`${ExtensionName.APP_MODERNIZATION_EXTENSION_NAME} extension has been updated. Reload VS Code to start the upgrade experience.`,
205222
"Reload Now"
206223
);
224+
// Reload acceptance is decoupled from the install-success signal above.
225+
sendInfo(operationId, {
226+
operationName: "java.dependency.upgradeFlow.reloadChoice",
227+
reloadChoice: reload === "Reload Now" ? "reload-accepted" : "reload-dismissed",
228+
});
207229
if (reload === "Reload Now") {
208-
sendInfo(operationId, {
209-
operationName: "java.dependency.upgradeFlow.result",
210-
upgradeFlowResult: "reload-accepted",
211-
});
212230
await commands.executeCommand("workbench.action.reloadWindow");
213-
} else {
214-
sendInfo(operationId, {
215-
operationName: "java.dependency.upgradeFlow.result",
216-
upgradeFlowResult: "reload-dismissed",
217-
});
218231
}
219232
return false;
220233
}
221234

222235
await checkOrPromptToEnableAppModExtension("upgrade");
223236

224-
// Wait briefly for the newly installed extension to activate
225-
await new Promise(resolve => setTimeout(resolve, 2000));
237+
// installExtension resolves on install completion, not when the extension's
238+
// activate() has run, so poll for the target state instead of a fixed sleep.
239+
const deadline = Date.now() + 15000;
240+
let newState = getExtensionState(extensionIdToCheck);
241+
while (newState !== "up-to-date" && Date.now() < deadline) {
242+
await new Promise(resolve => setTimeout(resolve, 500));
243+
newState = getExtensionState(extensionIdToCheck);
244+
}
226245

227-
// Re-check if the newly installed extension is active and meets version requirement
228-
const newState = getExtensionState(extensionIdToCheck);
229246
const canProceed = newState === "up-to-date";
230247
sendInfo(operationId, {
231248
operationName: "java.dependency.upgradeFlow.result",

0 commit comments

Comments
 (0)