| 1 | import { describe, expect, it } from "vite-plus/test"; |
| 2 | |
| 3 | import { CursorTransportFailure } from "./transportFailure.ts"; |
| 4 | |
| 5 | const diagnostic = "Error: RetriableError: WritableIterable is closed"; |
| 6 | |
| 7 | function failureFor(chunks: string[]) { |
| 8 | const reply = new CursorTransportFailure(); |
| 9 | for (const chunk of chunks) reply.push(chunk); |
| 10 | return reply.failure; |
| 11 | } |
| 12 | |
| 13 | describe("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 | }); |