Skip to content

Git exec(): child killed by a signal rejects with new Error('') and loses the signal information #84

Description

@joewalker

Observed behavior

The internal exec helper in src/util/git.ts resolves/rejects on the close event:

cmdProcess.on('close', (code: number): void => {
  if (code === 0) {
    resolve(outputs.join(''));
  } else {
    reject(new Error(outputs.join('')));
  }
});

Node's documentation says code may be null if the child was terminated by a signal (the signal name is the second argument to the listener). In that case:

  1. The type annotation code: number is wrong (it can be null).
  2. The rejection becomes new Error('') if the child was killed before producing any output, with no indication that it was killed or by which signal.

Expected behavior

The error should communicate either the non-zero exit code or the signal name, so a caller (or a developer reading logs) can tell why git terminated.

Minimal reproduction

import { spawn } from 'node:child_process';
const child = spawn('sleep', ['10']);
const outputs = [];
child.stdout?.on('data', d => outputs.push(String(d)));
child.stderr?.on('data', d => outputs.push(String(d)));
child.on('close', (code, signal) => {
  console.log('code=', code, 'signal=', signal);
  if (code === 0) { console.log('resolve', JSON.stringify(outputs.join(''))); }
  else { console.log('reject', JSON.stringify(outputs.join(''))); }
});
setTimeout(() => child.kill('SIGTERM'), 50);
// -> code= null signal= SIGTERM
// -> reject \"\"

Suggested fix

cmdProcess.on('close', (code: number | null, signal: NodeJS.Signals | null): void => {
  if (code === 0) {
    resolve(outputs.join(''));
    return;
  }
  const detail = outputs.join('');
  const reason = signal != null
    ? `git was killed by ${signal}`
    : `git exited with code ${code}`;
  reject(new Error(detail ? `${reason}: ${detail}` : reason));
});

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    S3Edge cases, confusing APIs, maintainability issues, or moderate performance problemsbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions