fix(cron): expose undelivered scheduled task results (#129160)

This commit is contained in:
Peter Steinberger
2026-08-25 01:37:24 -07:00
committed by GitHub
parent 063fcaf89e
commit bb0dc4629a
2 changed files with 72 additions and 4 deletions
+64
View File
@@ -394,6 +394,70 @@ describe("printCronList", () => {
expect(singleLine).not.toContain("(1x)");
});
it.each([
{ label: "required", bestEffort: false },
{ label: "best-effort", bestEffort: true },
{ label: "default", bestEffort: undefined },
])(
"makes $label undelivered automation output visible without changing JSON status",
({ bestEffort }) => {
const job = createBaseJob({
id: "undelivered-job",
delivery: {
mode: "announce",
...(bestEffort === undefined ? {} : { bestEffort }),
},
state: {
lastRunStatus: "ok",
lastDeliveryStatus: "not-delivered",
lastDeliveryError: "primary route rejected",
},
});
const list = createRuntimeLogCapture();
printCronList([job], list.runtime);
expectLogsToInclude(list.logs, "ok (not delivered)");
const show = createRuntimeLogCapture();
printCronShow(job, show.runtime);
expectLogsToInclude(show.logs, "status: ok (not delivered)");
expectLogsToInclude(show.logs, "last delivery error: primary route rejected");
expect(enrichCronJsonWithStatus(job)).toMatchObject({
status: "ok",
state: { lastRunStatus: "ok", lastDeliveryStatus: "not-delivered" },
});
expect(enrichCronJsonWithStatus({ jobs: [job] })).toMatchObject({
jobs: [{ status: "ok" }],
});
},
);
it.each([
{ label: "disabled", enabled: false, runStatus: "ok" as const, expectedStatus: "disabled" },
{ label: "running", enabled: true, runStatus: "ok" as const, expectedStatus: "running" },
{ label: "failed", enabled: true, runStatus: "error" as const, expectedStatus: "error" },
])(
"does not let prior non-delivery override a $label automation",
({ enabled, runStatus, expectedStatus }) => {
const job = createBaseJob({
enabled,
state: {
lastRunStatus: runStatus,
lastDeliveryStatus: "not-delivered",
...(expectedStatus === "running" ? { runningAtMs: Date.now() } : {}),
},
});
const show = createRuntimeLogCapture();
printCronShow(job, show.runtime);
expectLogsToInclude(show.logs, `status: ${expectedStatus}`);
expect(show.logs.join("\n")).not.toContain("ok (not delivered)");
expect(enrichCronJsonWithStatus(job)).toMatchObject({ status: expectedStatus });
},
);
it("shows why the scheduler auto-disabled a job without changing JSON status", () => {
const runFailures = createBaseJob({
id: "auto-disabled-runs",
+8 -4
View File
@@ -198,12 +198,16 @@ function decorateStatusWithFailures(status: string, consecutiveErrors: number |
function formatCronStatusForDisplay(job: CronJob): string {
const state = job.state ?? {};
if (computeStatus(job) === "disabled" && state.autoDisabled) {
const status = computeStatus(job);
if (status === "disabled" && state.autoDisabled) {
return state.autoDisabled.reason === "schedule-errors"
? "disabled (schedule)"
: `disabled (${state.autoDisabled.consecutiveErrors}x)`;
}
return decorateStatusWithFailures(computeStatus(job), state.consecutiveErrors);
if (status === "ok" && state.lastDeliveryStatus === "not-delivered") {
return "ok (not delivered)";
}
return decorateStatusWithFailures(status, state.consecutiveErrors);
}
export function handleCronCliError(err: unknown) {
@@ -513,13 +517,13 @@ export function printCronList(
);
const coloredStatus = (() => {
if (statusRaw === "ok") {
if (statusRaw === "ok" && state.lastDeliveryStatus !== "not-delivered") {
return colorize(rich, theme.success, statusLabel);
}
if (statusRaw === "error") {
return colorize(rich, theme.error, statusLabel);
}
if (statusRaw === "running") {
if (statusRaw === "running" || statusRaw === "ok") {
return colorize(rich, theme.warn, statusLabel);
}
if (statusRaw === "skipped") {