Skip to content

Commit dd130f8

Browse files
committed
Adds better git error handling/logging
1 parent 3c31d1a commit dd130f8

File tree

2 files changed

+41
-41
lines changed

2 files changed

+41
-41
lines changed

src/git/git.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ export async function git<TOut extends string | Buffer>(options: GitCommandOptio
176176
throw ex;
177177

178178
default: {
179-
const result = defaultExceptionHandler(ex, options, ...args);
179+
const result = defaultExceptionHandler(ex, options.cwd, start);
180180
exception = undefined;
181181
return result as TOut;
182182
}
@@ -186,40 +186,49 @@ export async function git<TOut extends string | Buffer>(options: GitCommandOptio
186186
pendingCommands.delete(command);
187187

188188
const duration = `${Strings.getDurationMilliseconds(start)} ms ${waiting ? '(await) ' : emptyStr}`;
189-
Logger.log(
190-
`${gitCommand} ${GlyphChars.Dot} ${
191-
exception !== undefined
192-
? `FAILED(${(exception.message || emptyStr).trim().split('\n', 1)[0]}) `
193-
: emptyStr
194-
}${duration}`
195-
);
189+
if (exception !== undefined) {
190+
Logger.warn(
191+
`[${runOpts.cwd}] Git ${(exception.message || exception.toString() || emptyStr)
192+
.trim()
193+
.replace(/fatal: /g, '')
194+
.replace(/\r?\n|\r/g, ` ${GlyphChars.Dot} `)} ${GlyphChars.Dot} ${duration}`
195+
);
196+
}
197+
else {
198+
Logger.log(`${gitCommand} ${GlyphChars.Dot} ${duration}`);
199+
}
196200
Logger.logGitCommand(
197201
`${gitCommand} ${GlyphChars.Dot} ${exception !== undefined ? 'FAILED ' : emptyStr}${duration}`,
198202
exception
199203
);
200204
}
201205
}
202206

203-
function defaultExceptionHandler(ex: Error, options: GitCommandOptions, ...args: any[]): string {
204-
const msg = ex && ex.toString();
205-
if (msg) {
207+
function defaultExceptionHandler(ex: Error, cwd: string | undefined, start?: [number, number]): string {
208+
const msg = ex.message || ex.toString();
209+
if (msg != null && msg.length !== 0) {
206210
for (const warning of Objects.values(GitWarnings)) {
207211
if (warning.test(msg)) {
208-
Logger.warn('git', ...args, ` cwd='${options.cwd}'\n\n `, msg.replace(/\r?\n|\r/g, ' '));
212+
const duration = start !== undefined ? `${Strings.getDurationMilliseconds(start)} ms` : emptyStr;
213+
Logger.warn(
214+
`[${cwd}] Git ${msg
215+
.trim()
216+
.replace(/fatal: /g, '')
217+
.replace(/\r?\n|\r/g, ` ${GlyphChars.Dot} `)} ${GlyphChars.Dot} ${duration}`
218+
);
209219
return emptyStr;
210220
}
211221
}
212-
}
213222

214-
const match = GitErrors.badRevision.exec(msg);
215-
if (match != null && match) {
216-
const [, ref] = match;
223+
const match = GitErrors.badRevision.exec(msg);
224+
if (match != null && match) {
225+
const [, ref] = match;
217226

218-
// Since looking up a ref with ^3 (e.g. looking for untracked files in a stash) can error on some versions of git just ignore it
219-
if (ref != null && ref.endsWith('^3')) return emptyStr;
227+
// Since looking up a ref with ^3 (e.g. looking for untracked files in a stash) can error on some versions of git just ignore it
228+
if (ref != null && ref.endsWith('^3')) return emptyStr;
229+
}
220230
}
221231

222-
Logger.error(ex, 'git', ...args, ` cwd='${options.cwd}'\n\n `);
223232
throw ex;
224233
}
225234

@@ -798,7 +807,7 @@ export class Git {
798807
return data.length === 0 ? undefined : [data.trim(), undefined];
799808
}
800809

801-
defaultExceptionHandler(ex, opts, ...params);
810+
defaultExceptionHandler(ex, opts.cwd);
802811
return undefined;
803812
}
804813
}
@@ -853,7 +862,7 @@ export class Git {
853862
return undefined;
854863
}
855864

856-
return defaultExceptionHandler(ex, opts, args) as TOut;
865+
return defaultExceptionHandler(ex, opts.cwd) as TOut;
857866
}
858867
}
859868

src/git/shell.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,6 @@ export function findExecutable(exe: string, args: string[]): { cmd: string; args
9999
return { cmd: exe, args: args };
100100
}
101101

102-
export class RunError extends Error {
103-
constructor(public readonly exitCode: number, ...args: any[]) {
104-
super(...args);
105-
106-
Error.captureStackTrace(this, RunError);
107-
}
108-
}
109-
110102
export interface RunOptions {
111103
cwd?: string;
112104
readonly env?: Record<string, any>;
@@ -132,6 +124,8 @@ export interface RunOptions {
132124
readonly stdinEncoding?: string;
133125
}
134126

127+
const bufferExceededRegex = /stdout maxBuffer( length)? exceeded/;
128+
135129
export function run<TOut extends string | Buffer>(
136130
command: string,
137131
args: any[],
@@ -145,18 +139,15 @@ export function run<TOut extends string | Buffer>(
145139
command,
146140
args,
147141
opts,
148-
(err: (Error & { code?: string | number }) | null, stdout, stderr) => {
149-
if (err != null) {
150-
reject(
151-
new RunError(
152-
err.code ? Number(err.code) : 0,
153-
err.message === 'stdout maxBuffer exceeded'
154-
? `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${
155-
opts.maxBuffer
156-
} bytes`
157-
: stderr || stdout
158-
)
159-
);
142+
(error: (Error & { code?: string | number }) | null, stdout, stderr) => {
143+
if (error != null) {
144+
if (bufferExceededRegex.test(error.message)) {
145+
error.message = `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${
146+
opts.maxBuffer
147+
} bytes`;
148+
}
149+
150+
reject(error);
160151

161152
return;
162153
}

0 commit comments

Comments
 (0)