fix(gateway): preserve provider failure outcomes (#110252)

This commit is contained in:
Peter Steinberger
2026-07-18 01:04:37 +01:00
committed by GitHub
parent d371ea1f01
commit 987e2ff436
2 changed files with 43 additions and 2 deletions

View File

@@ -224,8 +224,12 @@ export function dispatchAgentRunFromGateway(params: {
.catch(async (err: unknown) => {
const aborted = isGatewayAgentAbortRejection(err, params.abortController.signal);
const renderedErr = formatForLog(err);
const stopReason = resolveGatewayAgentAbortStopReason(params.abortController.signal);
const timeoutPhase = aborted ? resolveGatewayAgentAbortTimeoutPhase(stopReason) : undefined;
const stopReason = aborted
? resolveGatewayAgentAbortStopReason(params.abortController.signal)
: undefined;
const timeoutPhase = stopReason
? resolveGatewayAgentAbortTimeoutPhase(stopReason)
: undefined;
if (taskTracked) {
tryFinalizeTrackedAgentTask({
runId: params.runId,

View File

@@ -19,6 +19,7 @@ import {
setDetachedTaskLifecycleRuntime,
} from "../../tasks/task-runtime.test-helpers.js";
import { withTempDir } from "../../test-helpers/temp-dir.js";
import { dispatchAgentRunFromGateway } from "./agent-run-dispatch.js";
import {
applyGatewaySubagentRegistryTestDeps,
getAgentTestMocks,
@@ -691,6 +692,42 @@ describe("gateway agent handler", () => {
});
});
it("settles ordinary async gateway agent rejections as failed", async () => {
const providerError = new Error("provider request failed");
mocks.agentCommand.mockRejectedValueOnce(providerError);
const context = makeContext();
const onSettled = vi.fn(() => true);
const respond = vi.fn();
dispatchAgentRunFromGateway({
ingressOpts: {
message: "background cli task",
sessionKey: "agent:main:main",
allowModelOverride: false,
},
runId: "agent-run-provider-error-settlement",
dedupeKeys: ["agent:agent-run-provider-error-settlement"],
abortController: new AbortController(),
cleanupAbortController: vi.fn(),
respond,
context,
taskTrackingMode: "none",
onSettled,
});
await waitForAssertion(() => {
expect(onSettled).toHaveBeenCalledWith({
terminalOutcome: {
reason: "failed",
status: "error",
error: "Error: provider request failed",
},
onRecovered: expect.any(Function),
});
expect(respond).toHaveBeenCalled();
});
});
it("does not overwrite operator-cancelled async gateway agent tasks after late completion", async () => {
await withTempDir({ prefix: "openclaw-gateway-agent-task-cancelled-" }, async (root) => {
useTestStateDir(root);