A dropped connection says so, instead of the generic error card
A user's run failed with the wizard's generic "check your Ollama settings" card and could not be replicated with the same key - because the key and model were never the problem: a raw error (a mid-run socket drop, a wifi/LTE switch, the app backgrounded by the phone OS) leaked out of the NDJSON reader as a DOMException, and the wizard can only show the generic card for unknown errors. The reader now classifies everything: abort -> "cancelled", stall -> "the model stopped responding", anything else on the wire -> "the connection dropped mid-run, try again". Pinned with a fetch stub that kills the stream mid-run in the wizard suite (95 checks). Contrast 0 findings, mobile 124/124, chat 101/101, regression 44/44, i18n 13/13, native 33/33. Version 0.4.1, SW -> freezmo-v70.
This commit is contained in:
parent
20bb08b0e7
commit
b70b0e83cf
6 changed files with 71 additions and 15 deletions
|
|
@ -225,6 +225,44 @@ for (const viewport of [{ width: 390, height: 844 }, { width: 360, height: 740 }
|
|||
await context.close();
|
||||
}
|
||||
|
||||
/* 4c. a dropped stream gets its own message, not the generic card ----- */
|
||||
{
|
||||
const { context, page } = await makePage(browser);
|
||||
await seed(page, { decks: [] });
|
||||
await page.addInitScript(() => {
|
||||
const original = window.fetch;
|
||||
window.fetch = (input, init) => {
|
||||
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
||||
if (!url.includes("/api/generate")) return original(input, init);
|
||||
const encoder = new TextEncoder();
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(
|
||||
encoder.encode(`${JSON.stringify({ type: "stage", stage: "generation", message: "Finding the key ideas…" })}\n`),
|
||||
);
|
||||
setTimeout(() => controller.error(new Error("socket dropped")), 300);
|
||||
},
|
||||
});
|
||||
return Promise.resolve(new Response(stream, { status: 200, headers: { "Content-Type": "application/x-ndjson" } }));
|
||||
};
|
||||
});
|
||||
|
||||
await page.goto(`${BASE}/create`, { waitUntil: "networkidle" });
|
||||
await page.waitForTimeout(300);
|
||||
await page.getByRole("button", { name: "Paste text instead" }).click();
|
||||
await page.locator("textarea").first().fill("Photosynthesis needs light and water.");
|
||||
await page.getByRole("button", { name: "Next" }).click();
|
||||
await page.getByRole("button", { name: "Next" }).click();
|
||||
await page.getByRole("button", { name: "Freeze my deck" }).click();
|
||||
await page.waitForTimeout(1400);
|
||||
check(
|
||||
"stream loss: the wizard explains the dropped connection",
|
||||
await page.getByText("The connection dropped mid-run").isVisible(),
|
||||
);
|
||||
check("stream loss: retry is offered", await page.getByRole("button", { name: "Retry" }).isVisible());
|
||||
await context.close();
|
||||
}
|
||||
|
||||
/* 5. leaving mid-run aborts: no surprise deck, no navigation --------- */
|
||||
{
|
||||
const { context, page } = await makePage(browser);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue