Node: promisify child_process.exec always rejects

Created on 20 Mar 2018  Â·  10Comments  Â·  Source: nodejs/node

  • Version:
    v8.9.4
  • Platform:
    Ubuntu 16.04

I'm having trouble promisifying child_process.exec. When I run with error or without, the promise is rejected. I've followed the docs and wrote this:

const { promisify } = require('util');
const execCallback = require('child_process').exec;
const exec = promisify(execCallback);

const fooBar = () => {
  const dir = `engine/Users/${user}`;
  const fileOne = `${process.cwd()}/${dir}/myFileOne.txt`;
  const fileTwo = `${process.cwd()}/${dir}/myFileTwo.txt`;
  const command = `diff --unchanged-group-format="" ${fileOne} ${fileTwo}`;

  return run(command)
    .then((stdout, stderr) => {
      console.log('ran diff');
      return stdout;
    })
    .catch(error => console.log('got error running diff'));
};

fooBar goes through the catch block with this error:

{
  killed: false,
  code: 1,
  signal: null,
  cmd: /*the correct diff cmd*/,
  stdout: /*the correct diff stdout*/,
  stderr: ''
}

An actual error (or at least a 'no such file') gives me code: 2, stdout: '', stderr: no such file error string

child_process promises

Most helpful comment

@benjamingr Submitted PR. (Thank you for the offer. I believe it worked, but I am still figuring out the system. Please have no qualms about suggestions/criticism.)

Cheers,
Tom

All 10 comments

I don't think this is an actual bug. diff returns 1 if files differ, 0 if they're the same.

∴ diff <(echo testing) <(echo testing)
∴ echo $?
0
∴ diff <(echo testing) <(echo testing2)
1c1
< testing
---
> testing2
∴ echo $?
1

The exec function considers any exit code other than 0 to be an error. Try running the code with the files being the same.

Yes, this is by design, this is also how the callback version works so it doesn't actually have to do with promises.

Try

  const command = `diff --unchanged-group-format="" ${fileOne} ${fileTwo} || true`;

Maybe we should add a clarification to the docs: "If the process exits with a non-zero status code the promise is rejected"

The docs for child_process exec already show that "Any exit code other than 0 is considered to be an error." https://github.com/nodejs/node/blame/master/doc/api/child_process.md#L193

@TomCoded correct, I was suggesting adding that clarification to the util.promisify section:

If this method is invoked as its [util.promisify()][]ed version, it returns
a Promise for an object with stdout and stderr properties. In case of an
error (including a non-zero status code), a rejected promise is returned, with the same error object given in the
callback, but with an additional two properties stdout and stderr.

Or something of the sort

@TomCoded thanks, definitely missed that. I just assumed it would be on a fatal error of some sort, and would have a stderr.

Checking the exit code will be fine.

@benjamingr Oh, yes, something in the promisify section might be helpful. Perhaps (including any error resulting in an exit code other than 0), to keep the language consistent and to disambiguate from "an error including a non-zero exit code"

@TomCoded would you be interested in submitting such a PR? (If you're unsure how to get started, let me know and we can walk through it on IRC/IM together, I also recommend checking out CONTRIBUTING.md)

Will do.

@benjamingr Submitted PR. (Thank you for the offer. I believe it worked, but I am still figuring out the system. Please have no qualms about suggestions/criticism.)

Cheers,
Tom

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danialkhansari picture danialkhansari  Â·  3Comments

vsemozhetbyt picture vsemozhetbyt  Â·  3Comments

stevenvachon picture stevenvachon  Â·  3Comments

addaleax picture addaleax  Â·  3Comments

loretoparisi picture loretoparisi  Â·  3Comments