Recover failed conversion workers and validate Nitro downloads correctly
CI / check (push) Successful in 1m36s
CI / deploy (push) Successful in 1m15s
CI / e2e (push) Successful in 21s

This commit is contained in:
Simo committed 2026-09-05 14:18:28 +02:00
1 parent a78d8256e0
commit 7880d5d5df
5 files changed
+91 -8

No files matched your search

@@ -0,0 +1,45 @@
// @vitest-environment node
import { EventEmitter } from "node:events";
import { afterEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
convert: vi.fn(() => ({ bundle: Buffer.from("converted") })),
icon: vi.fn(() => Buffer.from("icon")),
}));
vi.mock("./index", () => ({
convertSwfToNitro: mocks.convert,
extractIconFromSwf: mocks.icon,
}));
vi.mock("node:worker_threads", () => ({
Worker: class extends EventEmitter {
postMessage() {
queueMicrotask(() =>
this.emit("error", new Error("worker module missing")),
);
}
},
}));
afterEach(() => {
vi.unstubAllEnvs();
vi.resetModules();
vi.clearAllMocks();
});
describe("conversion worker recovery", () => {
it("falls back when worker startup rejects the conversion job", async () => {
vi.stubEnv("NODE_ENV", "production");
vi.stubEnv("VITEST", undefined);
const { convertSwfToNitroAsync } = await import("./conversion-pool");
const data = Buffer.from("SWF");
const result = await convertSwfToNitroAsync(data, "chair");
expect(result.bundle.toString()).toBe("converted");
expect(mocks.convert).toHaveBeenCalledWith(data, "chair");
});
it("recovers icon extraction from a worker startup error", async () => {
vi.stubEnv("NODE_ENV", "production");
vi.stubEnv("VITEST", undefined);
const { extractIconFromSwfAsync } = await import("./conversion-pool");
expect(
(await extractIconFromSwfAsync(Buffer.from("SWF"), "chair"))?.toString(),
).toBe("icon");
});
});
+6 -4
View File
@@ -154,8 +154,10 @@ export async function convertSwfToNitroAsync(
buffer: Buffer,
classname: string,
): Promise<ConversionResult> {
const res = await run({ type: "convert", buffer, classname });
if (res.ok && res.result) return res.result;
const res = await run({ type: "convert", buffer, classname }).catch(
() => null,
);
if (res?.ok && res.result) return res.result;
// Worker failed for this item — fall back to the main thread.
return convertSwfToNitro(buffer, classname);
}
@@ -164,7 +166,7 @@ export async function extractIconFromSwfAsync(
buffer: Buffer,
classname: string,
): Promise<Buffer | null> {
const res = await run({ type: "icon", buffer, classname });
if (res.ok) return res.icon ?? null;
const res = await run({ type: "icon", buffer, classname }).catch(() => null);
if (res?.ok) return res.icon ?? null;
return extractIconFromSwf(buffer, classname);
}