mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(gateway): retain settled cleanup failures
This commit is contained in:
@@ -136,6 +136,10 @@ snapshot, so re-read them on every reconnect.
|
||||
|
||||
### Present system-agent QR codes
|
||||
|
||||
System-agent setup is administrative. Request `operator.admin` when pairing the
|
||||
device; every `openclaw.chat` call in this flow, including setup, polling,
|
||||
cancellation, and reset, requires that scope.
|
||||
|
||||
Advertise `GATEWAY_CLIENT_CAPS.SYSTEM_AGENT_QR_CODE` only when the client can
|
||||
render a QR image. A capable `openclaw.chat` session can then receive a QR
|
||||
`step` through the same wizard-step contract used for other setup controls:
|
||||
|
||||
@@ -216,4 +216,31 @@ describe("system-agent session lifecycle", () => {
|
||||
await retirementSettlement;
|
||||
expect(sessions.size).toBe(0);
|
||||
});
|
||||
|
||||
it("retains a settled initialization cleanup failure until retirement reports it once", async () => {
|
||||
const requestError = new Error("request failed before retirement");
|
||||
const cleanupError = new Error("cleanup failed before retirement");
|
||||
const sessions = new Map() as Sessions;
|
||||
const wizardSessions = new Map() as GatewayRequestContext["wizardSessions"];
|
||||
const initialization = initializeSystemAgentSession(
|
||||
sessions,
|
||||
"failed-session",
|
||||
async ({ ownEngine }) => {
|
||||
ownEngine(
|
||||
session("device:one", async () => {
|
||||
throw cleanupError;
|
||||
}).engine,
|
||||
);
|
||||
throw requestError;
|
||||
},
|
||||
);
|
||||
|
||||
await expect(initialization).rejects.toBe(requestError);
|
||||
await expect(
|
||||
retireAndDisposeSystemAgentSessions({ sessions, wizardSessions }),
|
||||
).rejects.toMatchObject({ errors: [cleanupError] });
|
||||
await expect(
|
||||
retireAndDisposeSystemAgentSessions({ sessions, wizardSessions }),
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ type ApprovalManager = NonNullable<GatewayRequestContext["systemAgentApprovalMan
|
||||
|
||||
const retiredStores = new WeakSet<SystemAgentSessions>();
|
||||
const pendingSessionSettlements = new WeakMap<SystemAgentSessions, Set<Promise<void>>>();
|
||||
const settledInitializationCleanupFailures = new WeakMap<SystemAgentSessions, Error[]>();
|
||||
const retiredWizardStores = new WeakSet<WizardSessions>();
|
||||
const pendingWizardAdmissions = new WeakMap<
|
||||
WizardSessions,
|
||||
@@ -77,8 +78,14 @@ export function initializeSystemAgentSession(
|
||||
await uncommittedEngine?.dispose();
|
||||
settlement.resolve();
|
||||
} catch (error) {
|
||||
// Cleanup belongs to the retiring owner, while the request keeps its original outcome.
|
||||
settlement.reject(error);
|
||||
const cleanupError = toErrorObject(error, "Unknown system-agent cleanup failure");
|
||||
if (!retiredStores.has(sessions)) {
|
||||
const failures = settledInitializationCleanupFailures.get(sessions) ?? [];
|
||||
failures.push(cleanupError);
|
||||
settledInitializationCleanupFailures.set(sessions, failures);
|
||||
}
|
||||
// Retirement already snapshots an in-flight lease; only earlier failures need escrow.
|
||||
settlement.reject(cleanupError);
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -209,8 +216,12 @@ export function retireAndDisposeSystemAgentSessions(params: {
|
||||
}): Promise<void> {
|
||||
retiredStores.add(params.sessions);
|
||||
retiredWizardStores.add(params.wizardSessions);
|
||||
const settledInitializationFailures =
|
||||
settledInitializationCleanupFailures.get(params.sessions) ?? [];
|
||||
settledInitializationCleanupFailures.delete(params.sessions);
|
||||
const disposals: Promise<unknown>[] = [
|
||||
...(pendingSessionSettlements.get(params.sessions) ?? []),
|
||||
...settledInitializationFailures.map((error) => Promise.reject(error)),
|
||||
...(pendingWizardAdmissions.get(params.wizardSessions) ?? []),
|
||||
];
|
||||
for (const [sessionId, session] of params.sessions) {
|
||||
|
||||
Reference in New Issue
Block a user