fix: send queue job payloads to the admin page as objects

BullMQ's asJSON() stringifies data, failedReason, stacktrace and
returnvalue. The Queues page reads them as objects, so payload repo IDs
never showed, failure reasons kept their JSON quotes, and a stack trace
rendered one block per character.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
tdurieuxandClaude Opus 5.5 committed 2026-10-08 14:46:01 +02:00
1 parent fd1bce74b4
commit cfd7b73de4
2 files changed
+42 -1

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
const { expect } = require("chai");
describe("admin queue jobs", function () {
it("returns job payloads, failure reasons and stacks as values, not JSON strings", async function () {
const queues = require("../src/queue");
const metrics = require("../src/queue/queueMetrics");
const router = require("../src/server/routes/admin").default;
const handler = router.stack.find(layer => layer.route?.path === "/queues").route.stack.at(-1).handle;
const originals = [queues.downloadQueue, queues.removeQueue, queues.cacheQueue, metrics.queryMetrics];
const failed = {
data: { repoId: "paper-7F2A" }, failedReason: "branch_not_found", stacktrace: ["Error: branch_not_found\n at fetch"], returnvalue: null,
// BullMQ's asJSON() stringifies these four fields.
asJSON() { return { id: "paper-7F2A", name: "paper-7F2A", data: JSON.stringify(this.data), failedReason: JSON.stringify(this.failedReason), stacktrace: JSON.stringify(this.stacktrace), returnvalue: JSON.stringify(this.returnvalue) }; },
};
const queue = { getJobCounts: async () => ({}), getWorkers: async () => [], isPaused: async () => false,
getJobs: async ([state]) => state === "failed" ? [failed] : [] };
queues.downloadQueue = queue; queues.removeQueue = queue; queues.cacheQueue = queue;
metrics.queryMetrics = async () => [];
try {
let body;
// The remove queue keeps this snapshot apart from other tests' cache entries.
await handler({ query: { queue: "remove" } }, { json: data => { body = data; } });
const job = body.jobs.find(j => j.id === "paper-7F2A");
expect(job.data).to.deep.equal({ repoId: "paper-7F2A" });
expect(job.failedReason).to.equal("branch_not_found");
expect(job.stacktrace).to.deep.equal(["Error: branch_not_found\n at fetch"]);
expect(job._state).to.equal("failed");
} finally {
[queues.downloadQueue, queues.removeQueue, queues.cacheQueue, metrics.queryMetrics] = originals;
}
});
});