mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
fix(studio): name the cause when a render request fails (#3424)
The render POST's catch took no binding, so the exception was discarded and every transport failure produced one sentence: "Could not reach render server. Use `hyperframes render` from the CLI instead." A dead server, a DNS failure, an aborted request and a server that died mid-render are all indistinguishable under that string — and it is not only a UI message, it is what travels into the feedback report. Three separate field reports carried it verbatim, one of them describing a render that fails every single time. A guaranteed reproduction that tells us nothing is worse than an intermittent one that does. Bind the error and append it. The CLI guidance stays, since it is still the right next step for the user; it just no longer stands alone. Regression test asserts both halves: the cause appears, and the guidance survives. It fails on the unfixed code with `expected 'Could not reach render server. Use `h…' to contain 'Failed to fetch'`.
This commit is contained in:
@@ -250,12 +250,19 @@ export function useRenderQueue(projectId: string | null) {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
} catch {
|
||||
} catch (err) {
|
||||
// The cause used to be discarded. Every failure — a dead server, an
|
||||
// aborted request, a DNS error, a mid-render crash — surfaced as the
|
||||
// same sentence, and this string is what travels into the feedback
|
||||
// report too, so field reports of a render that fails *every time*
|
||||
// still carried nothing to act on. Keep the CLI guidance, name the
|
||||
// cause after it.
|
||||
const cause = err instanceof Error ? err.message : String(err);
|
||||
const failedJob: RenderJob = {
|
||||
id: generateId(),
|
||||
status: "failed",
|
||||
progress: 0,
|
||||
error: "Could not reach render server. Use `hyperframes render` from the CLI instead.",
|
||||
error: `Could not reach render server: ${cause}. Use \`hyperframes render\` from the CLI instead.`,
|
||||
filename: "Export failed",
|
||||
createdAt: startTime,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
// The render POST's catch used to discard its error, so a dead server, a DNS
|
||||
// failure and a mid-render crash all produced one sentence. That string is also
|
||||
// what travels into the feedback report, so three field reports — one of them a
|
||||
// render that failed EVERY time — arrived with nothing to act on.
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { mountRenderQueue } from "./renderQueueTestHarness";
|
||||
|
||||
vi.mock("./useFfmpegStatus", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("./useFfmpegStatus")>()),
|
||||
useFfmpegStatus: () => ({ status: { ok: true }, checking: false, recheck: vi.fn() }),
|
||||
}));
|
||||
vi.mock("../../telemetry/events", () => ({ trackStudioRenderStart: vi.fn() }));
|
||||
|
||||
const { useRenderQueue } = await import("./useRenderQueue");
|
||||
|
||||
let queue: ReturnType<typeof mountRenderQueue> | null = null;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(() => Promise.reject(new TypeError("Failed to fetch"))),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
queue?.unmount();
|
||||
queue = null;
|
||||
document.body.innerHTML = "";
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe("useRenderQueue transport failure", () => {
|
||||
it("names the cause instead of collapsing every failure into one sentence", async () => {
|
||||
queue = mountRenderQueue(useRenderQueue);
|
||||
const { act } = await import("react");
|
||||
await act(async () => {
|
||||
await queue?.api().startRender({});
|
||||
});
|
||||
|
||||
const job = queue.api().jobs.at(-1);
|
||||
expect(job?.status).toBe("failed");
|
||||
expect(job?.error).toContain("Failed to fetch");
|
||||
// The CLI guidance still earns its place; it just no longer stands alone.
|
||||
expect(job?.error).toContain("hyperframes render");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user