Skip to content
Source
Sign inSign up

transportFailure.ts

50 lines1.5 KB

1const maxLineLength = 4096;
2// Cursor also uses RetriableError for agent-loop failures; preserve those diagnostics.
3const transportError =
4 /^Error: (?:RetriableError: (?!\[internal\]).+|ConnectError: \[(?:unavailable|aborted|deadline_exceeded)\].*)$/;
5const serverError = "Something went wrong communicating with the server. Please try again.";
6​
7interface ReplyState {
8 disqualified: boolean;
9 failure: string | undefined;
11​
12function consumeLine(state: ReplyState, line: string) {
13 if (state.disqualified) return;
14 const text = line.trimEnd();
15 if (transportError.test(text) || text === serverError) {
16 state.failure = text;
17 } else if (text.trim() !== "" && !(state.failure && /^\s+at\s/.test(text))) {
18 // Classify only whole-item dumps; explanations may quote the same diagnostic.
19 state.disqualified = true;
20 state.failure = undefined;
21 }
23​
24export class CursorTransportFailure {
25 private state: ReplyState = { disqualified: false, failure: undefined };
26 private line = "";
27​
28 push(text: string) {
29 for (const [index, part] of text.split("\n").entries()) {
30 if (this.state.disqualified) return;
31 if (index > 0) {
32 consumeLine(this.state, this.line);
33 this.line = "";
34 }
35 if (this.line.length + part.length > maxLineLength) {
36 this.state.disqualified = true;
37 this.state.failure = undefined;
38 this.line = "";
39 return;
40 }
41 this.line += part;
42 }
43 }
44​
45 get failure() {
46 const state = { ...this.state };
47 consumeLine(state, this.line);
48 return state.failure;
49 }