fix(robomp): suppress superseded recent failures

This commit is contained in:
lycaon
2026-06-17 22:43:59 -06:00
parent 1961b830ba
commit feb04e8a37
2 changed files with 119 additions and 0 deletions
+99
View File
@@ -614,4 +614,103 @@ describe("buildWorkItems", () => {
expect(items[0].latestEvent?.delivery_id).toBe("live-older-3");
});
test("suppresses an orphan failed recent event superseded by a newer done recent event for the same absent issue", () => {
const items = buildWorkItems(
status({
recent_events: [
recentEvent({
delivery_id: "done-newer-orphan",
issue_key: "owner/repo#30",
state: "done",
received_at: "2026-06-17T00:06:00Z",
last_error: null,
}),
recentEvent({
delivery_id: "failed-older-orphan",
issue_key: "owner/repo#30",
received_at: "2026-06-17T00:04:00Z",
last_error: "superseded orphan failure",
}),
],
}),
);
expect(items.some((item) => item.deliveryId === "failed-older-orphan")).toBe(false);
expect(items).toEqual([]);
});
test("suppresses an orphan failed recent event when a newer queued event appears later in the list", () => {
const items = buildWorkItems(
status({
recent_events: [
recentEvent({
delivery_id: "failed-older-out-of-order",
issue_key: "owner/repo#32",
received_at: "2026-06-17T00:04:00Z",
last_error: "older failure",
}),
recentEvent({
delivery_id: "queued-newer-out-of-order",
issue_key: "owner/repo#32",
state: "queued",
received_at: "2026-06-17T00:06:00Z",
last_error: null,
}),
],
}),
);
expect(items).toEqual([]);
});
test("suppresses a same-timestamp orphan failure when a non-failed recent event exists", () => {
const items = buildWorkItems(
status({
recent_events: [
recentEvent({
delivery_id: "failed-same-time",
issue_key: "owner/repo#33",
received_at: "2026-06-17T00:06:00Z",
last_error: "ambiguous failure",
}),
recentEvent({
delivery_id: "done-same-time",
issue_key: "owner/repo#33",
state: "done",
received_at: "2026-06-17T00:06:00Z",
last_error: null,
}),
],
}),
);
expect(items).toEqual([]);
});
test("renders an orphan failed recent event that is the newest for an absent issue", () => {
const items = buildWorkItems(
status({
recent_events: [
recentEvent({
delivery_id: "failed-newest-orphan",
issue_key: "owner/repo#31",
received_at: "2026-06-17T00:06:00Z",
last_error: "current orphan failure",
}),
recentEvent({
delivery_id: "done-older-orphan",
issue_key: "owner/repo#31",
state: "done",
received_at: "2026-06-17T00:04:00Z",
last_error: null,
}),
],
}),
);
expect(items).toHaveLength(1);
expect(items[0]).toMatchObject({
key: "owner/repo#31",
deliveryId: "failed-newest-orphan",
bucket: "failed",
error: "current orphan failure",
});
});
});
+20
View File
@@ -142,6 +142,19 @@ export function buildWorkItems(status: StatusResponse): WorkItem[] {
items.push(orphanLiveItem(key, null, true));
}
const newestRecentByKey = new Map<string, RecentEvent>();
for (const event of status.recent_events) {
if (!event.issue_key) continue;
const current = newestRecentByKey.get(event.issue_key);
const eventTs = parseTs(event.received_at);
const currentTs = current ? parseTs(current.received_at) : 0;
const nonFailedBreaksTie =
current != null && eventTs === currentTs && current.state === "failed" && event.state !== "failed";
if (!current || eventTs > currentTs || nonFailedBreaksTie) {
newestRecentByKey.set(event.issue_key, event);
}
}
for (const event of status.recent_events) {
if (event.state !== "failed" || !event.delivery_id || seen.has(event.delivery_id)) continue;
if (event.issue_key) {
@@ -149,6 +162,13 @@ export function buildWorkItems(status: StatusResponse): WorkItem[] {
if (latest && (latest.delivery_id !== event.delivery_id || latest.state !== "failed")) {
continue;
}
// For issues outside the capped `status.issues` window, fall back to the
// newest recent event for this issue_key. If a newer (or non-failed)
// delivery exists for the same issue, this older failed orphan is stale.
const newestRecent = newestRecentByKey.get(event.issue_key);
if (newestRecent && (newestRecent.delivery_id !== event.delivery_id || newestRecent.state !== "failed")) {
continue;
}
if (seen.has(event.issue_key)) continue;
}