From dd130f86c07a3de60dbb8cb1b5431688e3c77c00 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 18 Apr 2019 01:40:05 -0400 Subject: [PATCH] Adds better git error handling/logging --- src/git/git.ts | 51 ++++++++++++++++++++++++++++++--------------------- src/git/shell.ts | 31 +++++++++++-------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/git/git.ts b/src/git/git.ts index 41d6066..864807b 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -176,7 +176,7 @@ export async function git(options: GitCommandOptio throw ex; default: { - const result = defaultExceptionHandler(ex, options, ...args); + const result = defaultExceptionHandler(ex, options.cwd, start); exception = undefined; return result as TOut; } @@ -186,13 +186,17 @@ export async function git(options: GitCommandOptio pendingCommands.delete(command); 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( `${gitCommand} ${GlyphChars.Dot} ${exception !== undefined ? 'FAILED ' : emptyStr}${duration}`, 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)) { 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; } } - } - 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; } @@ -798,7 +807,7 @@ export class Git { return data.length === 0 ? undefined : [data.trim(), undefined]; } - defaultExceptionHandler(ex, opts, ...params); + defaultExceptionHandler(ex, opts.cwd); return undefined; } } @@ -853,7 +862,7 @@ export class Git { return undefined; } - return defaultExceptionHandler(ex, opts, args) as TOut; + return defaultExceptionHandler(ex, opts.cwd) as TOut; } } diff --git a/src/git/shell.ts b/src/git/shell.ts index db07411..758799a 100644 --- a/src/git/shell.ts +++ b/src/git/shell.ts @@ -99,14 +99,6 @@ export function findExecutable(exe: string, args: string[]): { cmd: string; 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 { cwd?: string; readonly env?: Record; @@ -132,6 +124,8 @@ export interface RunOptions { readonly stdinEncoding?: string; } +const bufferExceededRegex = /stdout maxBuffer( length)? exceeded/; + export function run( command: string, args: any[], @@ -145,18 +139,15 @@ export function run( command, args, 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; }