diff --git a/apps/worker/src/processors/eoc-push.ts b/apps/worker/src/processors/eoc-push.ts index 504d123..5b01b79 100644 --- a/apps/worker/src/processors/eoc-push.ts +++ b/apps/worker/src/processors/eoc-push.ts @@ -139,7 +139,16 @@ export async function pushOpsSummaryToEoc(redis: Redis): Promise return { ok: false, status: null, error: "ops summary cache is not a JSON object" }; } - const body = JSON.stringify(mapPayloadForEoc(parsed as Record)); + let body: string; + try { + body = JSON.stringify(mapPayloadForEoc(parsed as Record)); + } catch (err) { + return { + ok: false, + status: null, + error: `payload mapping failed: ${err instanceof Error ? err.message : String(err)}`, + }; + } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), EOC_PUSH_TIMEOUT_MS); diff --git a/apps/worker/test/eoc-push.test.ts b/apps/worker/test/eoc-push.test.ts index 43c1fcc..c7ee62f 100644 --- a/apps/worker/test/eoc-push.test.ts +++ b/apps/worker/test/eoc-push.test.ts @@ -135,4 +135,25 @@ describe("pushOpsSummaryToEoc", () => { globalThis.fetch = originalFetch; } }); + + it("does not throw when payload mapping fails", async () => { + process.env.EOC_URL = "https://eoc.example.com"; + process.env.EOC_PUSH_TOKEN = "tok"; + await redis.set( + "ops:summary:cache", + JSON.stringify({ + as_of: new Date().toISOString(), + app: { app: "cibello" }, + wall: { boards: [{ title: 123, tiles: "nej" }] }, + }), + "EX", + 60, + ); + + await expect(pushOpsSummaryToEoc(redis)).resolves.toEqual({ + ok: false, + status: null, + error: expect.stringMatching(/payload mapping failed/), + }); + }); });