feat: retry failed alert deliveries

This commit is contained in:
2026-07-19 12:58:53 +08:00
parent 00928b72e4
commit 1e01f3295e
9 changed files with 74 additions and 9 deletions
+26
View File
@@ -0,0 +1,26 @@
import assert from "node:assert/strict";
import { after, test } from "node:test";
import { randomUUID } from "node:crypto";
import { rmSync } from "node:fs";
const databasePath = `/tmp/mebbling-alerts-${randomUUID()}.db`;
process.env.DATABASE_PATH = databasePath;
process.env.ALERT_WEBHOOK_URL = "https://alerts.example.test/hook";
delete process.env.HUB_BUILD;
let database: typeof import("../lib/db").db | undefined;
after(() => { database?.close(); rmSync(databasePath, { force: true }); rmSync(`${databasePath}-wal`, { force: true }); rmSync(`${databasePath}-shm`, { force: true }); delete process.env.ALERT_WEBHOOK_URL; });
test("persists failed alerts for exponential-backoff retry", async () => {
const { db } = await import("../lib/db"); database = db;
const { deliverNextAlert, sendAlert } = await import("../lib/alerts");
assert.equal(sendAlert("test", "Test alert", "delivery should retry"), true);
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response("unavailable", { status: 503 });
try { assert.equal(await deliverNextAlert(), true); } finally { globalThis.fetch = originalFetch; }
const delivery = db.prepare("SELECT status,attempts,last_error FROM alert_deliveries").get() as { status: string; attempts: number; last_error: string };
assert.equal(delivery.status, "queued");
assert.equal(delivery.attempts, 1);
assert.match(delivery.last_error, /503/);
});