Skip to content

Commit 1e4993f

Browse files
committed
Fixes issues with Git error handling
1 parent d4bebd6 commit 1e4993f

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

src/env/node/git/git.ts

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,27 @@ const resetErrorAndReason: [RegExp, ResetErrorReason][] = [
190190
[GitErrors.unmergedChanges, ResetErrorReason.UnmergedChanges],
191191
];
192192

193+
export class GitError extends Error {
194+
readonly cmd: string | undefined;
195+
readonly exitCode: number | string | undefined;
196+
readonly stdout: string | undefined;
197+
readonly stderr: string | undefined;
198+
199+
constructor(private readonly original: Error) {
200+
if (original instanceof RunError) {
201+
super(original.stderr || original.stdout || original.message);
202+
this.stdout = original.stdout;
203+
this.stderr = original.stderr;
204+
this.cmd = original.cmd;
205+
this.exitCode = original.code;
206+
} else {
207+
super(original.message);
208+
}
209+
210+
Error.captureStackTrace?.(this, GitError);
211+
}
212+
}
213+
193214
export class Git {
194215
/** Map of running git commands -- avoids running duplicate overlaping commands */
195216
private readonly pendingCommands = new Map<string, Promise<RunResult<string | Buffer>>>();
@@ -275,22 +296,14 @@ export class Git {
275296
const result = await promise;
276297
return result.stdout as T;
277298
} catch (ex) {
278-
exception = ex;
299+
if (errorHandling === GitErrorHandling.Ignore) return '' as T;
279300

280-
switch (errorHandling) {
281-
case GitErrorHandling.Ignore:
282-
exception = undefined;
283-
return '' as T;
301+
exception = new GitError(ex);
302+
if (errorHandling === GitErrorHandling.Throw) throw exception;
284303

285-
case GitErrorHandling.Throw:
286-
throw ex;
287-
288-
default: {
289-
const result = defaultExceptionHandler(ex, options.cwd, start);
290-
exception = undefined;
291-
return result as T;
292-
}
293-
}
304+
const result = defaultExceptionHandler(ex, options.cwd, start);
305+
exception = undefined;
306+
return result as T;
294307
} finally {
295308
this.pendingCommands.delete(command);
296309
this.logGitCommand(gitCommand, exception, getDurationMilliseconds(start), waiting);
@@ -354,10 +367,8 @@ export class Git {
354367
if (ex?.name === 'AbortError') {
355368
exception = new CancelledRunError(command, true);
356369
} else {
357-
exception = ex;
370+
exception = new GitError(ex);
358371
}
359-
360-
exception = ex;
361372
});
362373
proc.once('exit', () => this.logGitCommand(gitCommand, exception, getDurationMilliseconds(start), false));
363374
return proc;
@@ -416,7 +427,10 @@ export class Git {
416427
let completed = false;
417428
let exception: Error | undefined;
418429

419-
proc.once('error', ex => (exception = ex?.name === 'AbortError' ? new CancelledRunError(command, true) : ex));
430+
proc.once(
431+
'error',
432+
ex => (exception = ex?.name === 'AbortError' ? new CancelledRunError(command, true) : new GitError(ex)),
433+
);
420434
proc.once('exit', (code, signal) => {
421435
if (signal === 'SIGTERM') {
422436
exception = new CancelledRunError(command, true, code ?? undefined, signal);

0 commit comments

Comments
 (0)