File size: 3,461 Bytes
3144483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
export type SpawnResult = {
  pid?: number;
  stdout: string;
  stderr: string;
  stdoutTruncatedBytes?: number;
  stderrTruncatedBytes?: number;
  preservedStdoutLines?: string[];
  preservedStderrLines?: string[];
  code: number | null;
  signal: NodeJS.Signals | null;
  killed: boolean;
  /** Completion of this invocation's cleanup; never an escaped-descendant inventory. */
  cleanup?: "normal" | "cooperative" | "forced" | "uncertain";
  termination: "exit" | "timeout" | "no-output-timeout" | "signal";
  noOutputTimedOut?: boolean;
  outputLimitExceeded?: boolean;
  outputErrorStream?: "stdout" | "stderr";
};

export const TIMEOUT_EXIT_CODE = 124;

export function createSanitizedCommandError(result: {
  code?: unknown;
  exitCode?: unknown;
  signal?: unknown;
  timedOut?: boolean;
  isCanceled?: boolean;
  isMaxBuffer?: boolean;
  isTerminated?: boolean;
}): Error {
  const code = typeof result.code === "string" ? result.code : undefined;
  const exitCode = typeof result.exitCode === "number" ? result.exitCode : undefined;
  const signal = typeof result.signal === "string" ? result.signal : undefined;
  const message = result.timedOut
    ? "Command timed out"
    : result.isMaxBuffer
      ? "Command output exceeded its capture limit"
      : result.isCanceled
        ? "Command was canceled"
        : result.isTerminated
          ? `Command was terminated${signal ? ` by ${signal}` : ""}`
          : exitCode !== undefined && exitCode !== 0
            ? `Command exited with code ${exitCode}`
            : `Command failed during launch or output capture${code ? ` (${code})` : ""}`;
  return Object.assign(new Error(message), {
    ...(code ? { code } : {}),
    ...(exitCode !== undefined ? { exitCode } : {}),
    ...(signal ? { signal } : {}),
  });
}

export function isPlainCommandExitFailure(result: {
  failed: boolean;
  exitCode?: unknown;
  signal?: unknown;
  cause?: unknown;
  timedOut?: boolean;
  isCanceled?: boolean;
  isMaxBuffer?: boolean;
  isTerminated?: boolean;
}): boolean {
  return (
    result.failed &&
    typeof result.exitCode === "number" &&
    result.exitCode !== 0 &&
    result.signal === undefined &&
    result.cause === undefined &&
    !result.timedOut &&
    !result.isCanceled &&
    !result.isMaxBuffer &&
    !result.isTerminated
  );
}

export function isPlainCommandSignalFailure(result: {
  failed: boolean;
  exitCode?: unknown;
  signal?: unknown;
  cause?: unknown;
  timedOut?: boolean;
  isCanceled?: boolean;
  isMaxBuffer?: boolean;
  isTerminated?: boolean;
}): boolean {
  return (
    result.failed &&
    result.exitCode === undefined &&
    typeof result.signal === "string" &&
    result.cause === undefined &&
    !result.timedOut &&
    !result.isCanceled &&
    !result.isMaxBuffer &&
    result.isTerminated === true
  );
}

export function resolveProcessExitCode(params: {
  explicitCode: number | null | undefined;
  childExitCode: number | null | undefined;
  resolvedSignal: NodeJS.Signals | null;
  usesWindowsExitCodeShim: boolean;
  timedOut: boolean;
  noOutputTimedOut: boolean;
  killIssuedByTimeout: boolean;
  killIssuedByAbort?: boolean;
}): number | null {
  return (
    params.explicitCode ??
    params.childExitCode ??
    (params.usesWindowsExitCodeShim &&
    params.resolvedSignal == null &&
    !params.timedOut &&
    !params.noOutputTimedOut &&
    !params.killIssuedByTimeout &&
    !params.killIssuedByAbort
      ? 0
      : null)
  );
}