Browse Source

Adds better git error handling/logging

main
Eric Amodio 5 years ago
parent
commit
dd130f86c0
2 changed files with 41 additions and 41 deletions
  1. +30
    -21
      src/git/git.ts
  2. +11
    -20
      src/git/shell.ts

+ 30
- 21
src/git/git.ts View File

@ -176,7 +176,7 @@ export async function git(options: GitCommandOptio
throw ex; throw ex;
default: { default: {
const result = defaultExceptionHandler(ex, options, ...args);
const result = defaultExceptionHandler(ex, options.cwd, start);
exception = undefined; exception = undefined;
return result as TOut; return result as TOut;
} }
@ -186,13 +186,17 @@ export async function git(options: GitCommandOptio
pendingCommands.delete(command); pendingCommands.delete(command);
const duration = `${Strings.getDurationMilliseconds(start)} ms ${waiting ? '(await) ' : emptyStr}`; const duration = `${Strings.getDurationMilliseconds(start)} ms ${waiting ? '(await) ' : emptyStr}`;
Logger.log(
`${gitCommand} ${GlyphChars.Dot} ${
exception !== undefined
? `FAILED(${(exception.message || emptyStr).trim().split('\n', 1)[0]}) `
: emptyStr
}${duration}`
);
if (exception !== undefined) {
Logger.warn(
`[${runOpts.cwd}] Git ${(exception.message || exception.toString() || emptyStr)
.trim()
.replace(/fatal: /g, '')
.replace(/\r?\n|\r/g, ` ${GlyphChars.Dot} `)} ${GlyphChars.Dot} ${duration}`
);
}
else {
Logger.log(`${gitCommand} ${GlyphChars.Dot} ${duration}`);
}
Logger.logGitCommand( Logger.logGitCommand(
`${gitCommand} ${GlyphChars.Dot} ${exception !== undefined ? 'FAILED ' : emptyStr}${duration}`, `${gitCommand} ${GlyphChars.Dot} ${exception !== undefined ? 'FAILED ' : emptyStr}${duration}`,
exception exception
@ -200,26 +204,31 @@ export async function git(options: GitCommandOptio
} }
} }
function defaultExceptionHandler(ex: Error, options: GitCommandOptions, ...args: any[]): string {
const msg = ex && ex.toString();
if (msg) {
function defaultExceptionHandler(ex: Error, cwd: string | undefined, start?: [number, number]): string {
const msg = ex.message || ex.toString();
if (msg != null && msg.length !== 0) {
for (const warning of Objects.values(GitWarnings)) { for (const warning of Objects.values(GitWarnings)) {
if (warning.test(msg)) { if (warning.test(msg)) {
Logger.warn('git', ...args, ` cwd='${options.cwd}'\n\n `, msg.replace(/\r?\n|\r/g, ' '));
const duration = start !== undefined ? `${Strings.getDurationMilliseconds(start)} ms` : emptyStr;
Logger.warn(
`[${cwd}] Git ${msg
.trim()
.replace(/fatal: /g, '')
.replace(/\r?\n|\r/g, ` ${GlyphChars.Dot} `)} ${GlyphChars.Dot} ${duration}`
);
return emptyStr; return emptyStr;
} }
} }
}
const match = GitErrors.badRevision.exec(msg);
if (match != null && match) {
const [, ref] = match;
const match = GitErrors.badRevision.exec(msg);
if (match != null && match) {
const [, ref] = match;
// 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
if (ref != null && ref.endsWith('^3')) return emptyStr;
// 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
if (ref != null && ref.endsWith('^3')) return emptyStr;
}
} }
Logger.error(ex, 'git', ...args, ` cwd='${options.cwd}'\n\n `);
throw ex; throw ex;
} }
@ -798,7 +807,7 @@ export class Git {
return data.length === 0 ? undefined : [data.trim(), undefined]; return data.length === 0 ? undefined : [data.trim(), undefined];
} }
defaultExceptionHandler(ex, opts, ...params);
defaultExceptionHandler(ex, opts.cwd);
return undefined; return undefined;
} }
} }
@ -853,7 +862,7 @@ export class Git {
return undefined; return undefined;
} }
return defaultExceptionHandler(ex, opts, args) as TOut;
return defaultExceptionHandler(ex, opts.cwd) as TOut;
} }
} }

+ 11
- 20
src/git/shell.ts View File

@ -99,14 +99,6 @@ export function findExecutable(exe: string, args: string[]): { cmd: string; args
return { cmd: exe, args: args }; return { cmd: exe, args: args };
} }
export class RunError extends Error {
constructor(public readonly exitCode: number, ...args: any[]) {
super(...args);
Error.captureStackTrace(this, RunError);
}
}
export interface RunOptions { export interface RunOptions {
cwd?: string; cwd?: string;
readonly env?: Record<string, any>; readonly env?: Record<string, any>;
@ -132,6 +124,8 @@ export interface RunOptions {
readonly stdinEncoding?: string; readonly stdinEncoding?: string;
} }
const bufferExceededRegex = /stdout maxBuffer( length)? exceeded/;
export function run<TOut extends string | Buffer>( export function run<TOut extends string | Buffer>(
command: string, command: string,
args: any[], args: any[],
@ -145,18 +139,15 @@ export function run(
command, command,
args, args,
opts, opts,
(err: (Error & { code?: string | number }) | null, stdout, stderr) => {
if (err != null) {
reject(
new RunError(
err.code ? Number(err.code) : 0,
err.message === 'stdout maxBuffer exceeded'
? `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${
opts.maxBuffer
} bytes`
: stderr || stdout
)
);
(error: (Error & { code?: string | number }) | null, stdout, stderr) => {
if (error != null) {
if (bufferExceededRegex.test(error.message)) {
error.message = `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${
opts.maxBuffer
} bytes`;
}
reject(error);
return; return;
} }

Loading…
Cancel
Save