fix: recover workbench session switchback hydration

This commit is contained in:
Codex
2026-06-26 13:38:22 +00:00
parent 22d29e4d87
commit ca583ba98a
@@ -1748,11 +1748,22 @@ async function switchAwayAndBack(command) {
const switchAway = await clickSession(alternateSessionId);
const awaySettle = await waitForWorkbenchSessionHydrated(page, alternateSessionId, { timeoutMs: 15000 });
const away = awaySettle.snapshot ?? await workbenchSessionSnapshot();
const switchBack = await gotoTarget("/workbench/sessions/" + encodeURIComponent(canarySessionId));
const backSettle = await waitForWorkbenchSessionHydrated(page, canarySessionId, { timeoutMs: 15000 });
const after = backSettle.snapshot ?? await workbenchSessionSnapshot();
const routeOk = after?.routeSessionId === canarySessionId;
const activeOk = after?.activeSessionId === canarySessionId;
let switchBack = await gotoTarget("/workbench/sessions/" + encodeURIComponent(canarySessionId));
let backSettle = await waitForWorkbenchSessionHydrated(page, canarySessionId, { timeoutMs: 15000 });
let after = backSettle.snapshot ?? await workbenchSessionSnapshot();
let switchBackRecovery = null;
let routeOk = after?.routeSessionId === canarySessionId;
let activeOk = after?.activeSessionId === canarySessionId;
if (!routeOk || !activeOk) {
switchBackRecovery = await recoverControlPageSessionHydration(canarySessionId, backSettle);
if (switchBackRecovery?.ok === true) {
switchBack = { ...switchBack, recoveryApplied: true, recoveryNavigation: switchBackRecovery.navigation, valuesRedacted: true };
backSettle = switchBackRecovery.settle;
after = switchBackRecovery.snapshot ?? after;
routeOk = after?.routeSessionId === canarySessionId;
activeOk = after?.activeSessionId === canarySessionId;
}
}
if (awaySettle.ok !== true) {
const error = new Error("switchAwayAndBack did not settle on the alternate session");
error.details = { canarySessionId, alternateSessionId, routeSessionId: away?.routeSessionId ?? null, activeSessionId: away?.activeSessionId ?? null, settle: awaySettle, pageId, valuesRedacted: true };
@@ -1760,7 +1771,7 @@ async function switchAwayAndBack(command) {
}
if (!routeOk || !activeOk) {
const error = new Error("switchAwayAndBack did not return to the canary session");
error.details = { canarySessionId, alternateSessionId, routeSessionId: after?.routeSessionId ?? null, activeSessionId: after?.activeSessionId ?? null, settle: backSettle, pageId, valuesRedacted: true };
error.details = { canarySessionId, alternateSessionId, routeSessionId: after?.routeSessionId ?? null, activeSessionId: after?.activeSessionId ?? null, settle: backSettle, recovery: switchBackRecovery, pageId, valuesRedacted: true };
throw error;
}
return {
@@ -1784,6 +1795,7 @@ async function switchAwayAndBack(command) {
},
switchBack,
backSettle,
switchBackRecovery,
routeSessionId: after?.routeSessionId ?? null,
activeSessionId: after?.activeSessionId ?? null,
routeOk,
@@ -1794,6 +1806,39 @@ async function switchAwayAndBack(command) {
};
}
async function recoverControlPageSessionHydration(sessionId, previousSettle) {
const observerHydration = observerPage && !observerPage.isClosed()
? await waitForWorkbenchSessionHydrated(observerPage, sessionId, { timeoutMs: 5000 })
: { ok: false, reason: "observer-page-unavailable", valuesRedacted: true };
if (observerHydration.ok !== true) {
return { ok: false, attempted: false, reason: "observer-session-not-hydrated", previousSettle, observerHydration, valuesRedacted: true };
}
await recreateControlPageForNavigation("switch-back-hydration-retry", 1);
const navigation = await gotoTarget("/workbench/sessions/" + encodeURIComponent(sessionId));
const settle = await waitForWorkbenchSessionHydrated(page, sessionId, { timeoutMs: 15000 });
const snapshot = settle.snapshot ?? await workbenchSessionSnapshot();
const routeOk = snapshot?.routeSessionId === sessionId;
const activeOk = snapshot?.activeSessionId === sessionId;
return {
ok: settle.ok === true && routeOk && activeOk,
attempted: true,
reason: settle.ok === true ? "control-page-recreated" : settle.reason || "control-session-hydration-retry-failed",
previousSettle,
observerHydration,
navigation,
settle,
snapshot: {
routeSessionId: snapshot?.routeSessionId ?? null,
activeSessionId: snapshot?.activeSessionId ?? null,
composerReady: snapshot?.composerReady === true,
messageCount: snapshot?.messageCount ?? null,
valuesRedacted: true,
},
pageId,
valuesRedacted: true,
};
}
async function assertSessionInvariant(command) {
const beforeUrl = currentPageUrl();
const snapshot = await workbenchSessionSnapshot();