1import { describe, expect, it } from "vite-plus/test";
2
3import { CursorTransportFailure } from "./transportFailure.ts";
4
5const diagnostic = "Error: RetriableError: WritableIterable is closed";
6
7function failureFor(chunks: string[]) {
8 const reply = new CursorTransportFailure();
9 for (const chunk of chunks) reply.push(chunk);
10 return reply.failure;
11}
12
13describe("CursorTransportFailure", () => {
14 it.each([
15 diagnostic,
16 "Error: ConnectError: [unavailable] transport closed",
17 "Error: ConnectError: [aborted] aborted",
18 "Error: ConnectError: [deadline_exceeded] timed out",
19 "Something went wrong communicating with the server. Please try again.",
20 ])("recognizes a terminal diagnostic: %s", (message) => {
21 expect(failureFor([message])).toBe(message);
22 expect(failureFor([...message])).toBe(message);
23 });
24
25 it("recognizes a standalone failure with a stack trace", () => {
26 expect(failureFor(["\n", diagnostic, "\n at send (cli.js:1:2)\n\n"])).toBe(diagnostic);
27 });
28
29 it.each([
30 "The error was " + diagnostic,
31 "This is an example of a transport error:\n" + diagnostic,
32 "I inspected the files.\n" + diagnostic,
33 "> " + diagnostic,
34 " " + diagnostic,
35 "```text\n" + diagnostic + "\n```",
36 "~~~\n" + diagnostic + "\n~~~",
37 diagnostic + "\nThis is an example of a transport error.",
38 "Error: ConnectError: [unauthenticated] sign in",
39 "Error: ConnectError: [permission_denied] subscription required",
40 "Error: HTTP 500 from the application being debugged",
41 "Error: RetriableError: [internal] Failed to run step, exceeded max retries",
42 "Error: RetriableError: [internal] Failed to run step, exceeded max retries\n at step (cli.js:1:2)",
43 ])("preserves prose, code and non-transport errors: %s", (message) => {
44 expect(failureFor([...message])).toBeUndefined();
45 });
46
47 it("tracks fences across long lines without retaining the answer", () => {
48 expect(failureFor(["```\n", "x".repeat(100_000), "\n", diagnostic])).toBeUndefined();
49 expect(failureFor(["```", "x".repeat(100_000), "\n", diagnostic])).toBeUndefined();
50 expect(failureFor(["x".repeat(100_000), "\n", diagnostic])).toBeUndefined();
51 });
52
53 it("does not retain a previous failure after new output", () => {
54 const reply = new CursorTransportFailure();
55 reply.push(diagnostic);
56 expect(reply.failure).toBe(diagnostic);
57 reply.push("\nRecovered successfully.");
58 expect(reply.failure).toBeUndefined();
59 });
60});