fix(clawsweeper): address review for automerge-openclaw-openclaw-84056 (1)

This commit is contained in:
clawsweeper
2026-05-19 21:04:59 +00:00
parent 9be6184f9d
commit 050c779cfa
2 changed files with 28 additions and 21 deletions

View File

@@ -1314,21 +1314,18 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
expectInitialLockReleasedBeforePostTurnWrite(lockEvents);
});
it("preserves provider prompt errors while carrying cleanup session takeover", async () => {
it("preserves provider prompt errors when cleanup reacquire detects session takeover", async () => {
const providerError = new Error("provider rejected request: HTTP 400");
let releasingCleanupLock = false;
let cleanupTakeover: EmbeddedAttemptSessionTakeoverError | undefined;
hoisted.flushPendingToolResultsAfterIdleMock.mockImplementation(async () => {
releasingCleanupLock = true;
let acquireCount = 0;
let cleanupReacquireSessionFile: string | undefined;
hoisted.acquireSessionWriteLockMock.mockImplementation(async (params) => {
acquireCount += 1;
if (acquireCount === 3) {
cleanupReacquireSessionFile = params.sessionFile;
await fs.appendFile(params.sessionFile, '{"type":"message","id":"takeover"}\n', "utf8");
}
return { release: async () => {} };
});
hoisted.acquireSessionWriteLockMock.mockImplementation(async (params) => ({
release: async () => {
if (releasingCleanupLock) {
cleanupTakeover = new EmbeddedAttemptSessionTakeoverError(params.sessionFile);
throw cleanupTakeover;
}
},
}));
const error = await createContextEngineAttemptRunner({
contextEngine: createContextEngineBootstrapAndAssemble(),
@@ -1342,8 +1339,13 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
expect(error).toBeInstanceOf(Error);
expect((error as Error).name).toBe("EmbeddedAttemptSessionTakeoverError");
expect((error as Error).message).toBe(providerError.message);
expect((error as Error).cause).toBe(cleanupTakeover);
expect((error as Error).cause).toBeInstanceOf(EmbeddedAttemptSessionTakeoverError);
if (!cleanupReacquireSessionFile) {
throw new Error("expected cleanup lock reacquire");
}
expect(((error as Error).cause as Error).message).toContain(cleanupReacquireSessionFile);
expect((error as { promptError?: unknown }).promptError).toBe(providerError);
expect(hoisted.flushPendingToolResultsAfterIdleMock).not.toHaveBeenCalled();
});
it("keeps cleanup session takeover fatal when no provider prompt error exists", async () => {

View File

@@ -5196,12 +5196,17 @@ export async function runEmbeddedAttempt(
} catch (err) {
cleanupError = err;
}
const synthesizedCleanupTakeoverError =
!cleanupError && promptError && sessionLockController.hasSessionTakeover()
? new EmbeddedAttemptSessionTakeoverError(params.sessionFile)
: undefined;
const cleanupFailure = cleanupError ?? synthesizedCleanupTakeoverError;
const shouldPreservePromptError = shouldPreservePromptErrorAfterCleanupError({
promptError,
cleanupError,
cleanupError: cleanupFailure,
});
emitDiagnosticRunCompleted?.(
cleanupError
cleanupFailure
? "error"
: beforeAgentRunBlocked
? "blocked"
@@ -5210,26 +5215,26 @@ export async function runEmbeddedAttempt(
: aborted || timedOut || idleTimedOut || timedOutDuringCompaction
? "aborted"
: "completed",
shouldPreservePromptError ? promptError : (cleanupError ?? promptError),
shouldPreservePromptError ? promptError : (cleanupFailure ?? promptError),
beforeAgentRunBlocked
? { blockedBy: beforeAgentRunBlockedBy ?? "before_agent_run" }
: undefined,
);
if (cleanupError) {
if (cleanupFailure) {
if (shouldPreservePromptError) {
log.warn(
`embedded attempt cleanup detected session takeover after prompt failure; preserving prompt error: ` +
`runId=${params.runId} sessionId=${params.sessionId} ` +
`promptError=${formatErrorMessage(promptError)} cleanupError=${formatErrorMessage(cleanupError)}`,
`promptError=${formatErrorMessage(promptError)} cleanupError=${formatErrorMessage(cleanupFailure)}`,
);
await Promise.reject(
new EmbeddedAttemptPromptErrorWithCleanupTakeoverError({
promptError,
cleanupError: cleanupError as EmbeddedAttemptSessionTakeoverError,
cleanupError: cleanupFailure as EmbeddedAttemptSessionTakeoverError,
}),
);
} else {
await Promise.reject(cleanupError);
await Promise.reject(cleanupFailure);
}
}
}