mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 10:59:57 +00:00
fix(cron): surface classified run failure causes
Surface classified cron failure causes without changing raw cron JSON error text. - add additive CLI `cause` output for finished run entries with `errorReason` - persist/backfill full `FailoverReason` values on cron run-log entries - thread provider context through cron finalization so provider-specific failure causes stay accurate - extend protocol/Swift models and regression coverage for CLI JSON, run-log parsing/search, alerts, and protocol conformance Verification: - `pnpm lint --threads=8` - `pnpm protocol:check` - `pnpm exec oxfmt --check src/cli/cron-cli/shared.ts src/cli/cron-cli/shared.cause-display.test.ts src/cron/run-log.ts src/cron/run-log.error-reason.test.ts src/cron/cron-protocol-conformance.test.ts src/cron/service.failure-alert.test.ts src/cron/service/timer.ts src/cron/service/ops.ts src/gateway/protocol/schema/cron.ts scripts/protocol-gen-swift.ts` - `git diff --check` - AWS Crabbox `cbx_8a6a65ab83b0` / `run_42b73a4a9750`: 4 files, 20 tests passed - autoreview clean, no accepted/actionable findings - GitHub CI/CodeQL/OpenGrep/Workflow Sanity green/skipped/neutral on `aa29b087b2587d0aed3d409de5e7a2c706c32cdf` Co-authored-by: Yoshikazu Terashi <yterashi@peperon-works.jp>
This commit is contained in:
committed by
GitHub
parent
57b1c0b3d9
commit
3104f36329
52
src/cli/cron-cli/shared.cause-display.test.ts
Normal file
52
src/cli/cron-cli/shared.cause-display.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { printCronJson } from "./shared.js";
|
||||
|
||||
describe("printCronJson cause display", () => {
|
||||
it("adds an additive cause without changing raw cron run errors", () => {
|
||||
let written: unknown;
|
||||
const original = defaultRuntime.writeJson;
|
||||
defaultRuntime.writeJson = (value: unknown) => {
|
||||
written = value;
|
||||
};
|
||||
try {
|
||||
printCronJson({
|
||||
entries: [
|
||||
{
|
||||
ts: 1,
|
||||
jobId: "job-1",
|
||||
action: "finished",
|
||||
status: "error",
|
||||
errorReason: "timeout",
|
||||
error: "cron: job execution timed out",
|
||||
},
|
||||
],
|
||||
});
|
||||
} finally {
|
||||
defaultRuntime.writeJson = original;
|
||||
}
|
||||
|
||||
const result = written as { entries: Array<Record<string, unknown>> };
|
||||
expect(result.entries[0]?.cause).toBe("timeout");
|
||||
expect(result.entries[0]?.error).toBe("cron: job execution timed out");
|
||||
expect(result.entries[0]?.errorReason).toBe("timeout");
|
||||
});
|
||||
|
||||
it("does not add cause fields to non-run-log entries", () => {
|
||||
let written: unknown;
|
||||
const original = defaultRuntime.writeJson;
|
||||
defaultRuntime.writeJson = (value: unknown) => {
|
||||
written = value;
|
||||
};
|
||||
try {
|
||||
printCronJson({
|
||||
entries: [{ errorReason: "timeout", status: "error" }],
|
||||
});
|
||||
} finally {
|
||||
defaultRuntime.writeJson = original;
|
||||
}
|
||||
|
||||
const result = written as { entries: Array<Record<string, unknown>> };
|
||||
expect(result.entries[0]?.cause).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -25,8 +25,31 @@ export const getCronChannelOptions = () => {
|
||||
return pluginIds.length > 0 ? ["last", ...pluginIds].join("|") : "last|<channel-id>";
|
||||
};
|
||||
|
||||
function addCronRunCauseFields(value: unknown): unknown {
|
||||
if (!value || typeof value !== "object") {
|
||||
return value;
|
||||
}
|
||||
const record = value as Record<string, unknown>;
|
||||
const entries = record.entries;
|
||||
if (!Array.isArray(entries)) {
|
||||
return value;
|
||||
}
|
||||
const nextEntries = entries.map((entry) => {
|
||||
if (!entry || typeof entry !== "object") {
|
||||
return entry;
|
||||
}
|
||||
const item = entry as Record<string, unknown>;
|
||||
if (item.action !== "finished" || typeof item.errorReason !== "string") {
|
||||
return item;
|
||||
}
|
||||
const cause = item.errorReason.trim();
|
||||
return cause ? Object.assign({}, item, { cause }) : item;
|
||||
});
|
||||
return { ...record, entries: nextEntries };
|
||||
}
|
||||
|
||||
export function printCronJson(value: unknown) {
|
||||
defaultRuntime.writeJson(value);
|
||||
defaultRuntime.writeJson(addCronRunCauseFields(value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user