fix(FN-1284): move terminal execution failures to in-review
- Move single-session and step-session executor failure paths to in-review after marking tasks failed - Route exhausted transient recovery retries to in-review instead of leaving tasks outside review flow - Move stuck-kill budget exhaustion failures in self-healing to in-review and update failure log wording - Add regression tests in executor and self-healing suites to verify in-review transitions on these failure states
This commit is contained in:
@@ -254,6 +254,7 @@ describe("TaskExecutor with semaphore", () => {
|
||||
});
|
||||
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-001", { status: "failed", error: expect.any(String) });
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-001", "in-review");
|
||||
expect(onError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -4909,7 +4910,7 @@ describe("TaskExecutor bounded recovery retries", () => {
|
||||
expect(onError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("escalates to failure when recovery retries are exhausted", async () => {
|
||||
it("moves task to in-review when transient retries are exhausted (single-session)", async () => {
|
||||
const store = createMockStore();
|
||||
const onError = vi.fn();
|
||||
|
||||
@@ -4932,12 +4933,13 @@ describe("TaskExecutor bounded recovery retries", () => {
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-001", expect.objectContaining({
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-001", {
|
||||
status: "failed",
|
||||
error: "socket hang up",
|
||||
recoveryRetryCount: null,
|
||||
nextRecoveryAt: null,
|
||||
}));
|
||||
});
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-001", "in-review");
|
||||
expect(store.moveTask).not.toHaveBeenCalledWith("FN-001", "todo");
|
||||
expect(onError).toHaveBeenCalled();
|
||||
});
|
||||
@@ -8591,7 +8593,7 @@ describe("StepSessionExecutor integration", () => {
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("exception from executeAll marks task as failed", async () => {
|
||||
it("moves task to in-review when step-session execution fails", async () => {
|
||||
const store = createStepSessionStore();
|
||||
|
||||
mockExecuteAll.mockRejectedValue(new Error("Infrastructure failure"));
|
||||
@@ -8605,6 +8607,28 @@ describe("StepSessionExecutor integration", () => {
|
||||
status: "failed",
|
||||
error: "Infrastructure failure",
|
||||
}));
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-200", "in-review");
|
||||
expect(onError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("moves task to in-review when transient retries are exhausted (step-session)", async () => {
|
||||
const store = createStepSessionStore();
|
||||
|
||||
mockExecuteAll.mockRejectedValue(new Error("socket hang up"));
|
||||
|
||||
const onError = vi.fn();
|
||||
const executor = new TaskExecutor(store, "/tmp/test", { onError });
|
||||
|
||||
await executor.execute(createTaskWithSteps({ recoveryRetryCount: 3 }));
|
||||
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-200", {
|
||||
status: "failed",
|
||||
error: "socket hang up",
|
||||
recoveryRetryCount: null,
|
||||
nextRecoveryAt: null,
|
||||
});
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-200", "in-review");
|
||||
expect(store.moveTask).not.toHaveBeenCalledWith("FN-200", "todo");
|
||||
expect(onError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user