Skip to content

promisify child_process.exec always rejects #19494

Closed

Description

@njtrettel
  • 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

Activity

  1. jiripospisil commented on Mar 20, 2018

    @jiripospisil

    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.

  2. added
    child_processIssues and PRs related to the child_process subsystem.
    promisesIssues and PRs related to ECMAScript promises.
    on Mar 20, 2018
  3. benjamingr commented on Mar 21, 2018

    @benjamingr
    Member

    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`;
    
  4. benjamingr commented on Mar 21, 2018

    @benjamingr
    Member

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

  5. TomCoded commented on Mar 21, 2018

    @TomCoded
    Contributor

    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

  6. benjamingr commented on Mar 21, 2018

    @benjamingr
    Member

    @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

  7. njtrettel commented on Mar 21, 2018

    @njtrettel
    Author

    @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.

  8. TomCoded commented on Mar 22, 2018

    @TomCoded
    Contributor

    @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"

  9. benjamingr commented on Mar 22, 2018

    @benjamingr
    Member

    @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)

  10. TomCoded commented on Mar 22, 2018

    @TomCoded
    Contributor

    Will do.

  11. TomCoded commented on Mar 22, 2018

    @TomCoded
    Contributor

    @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

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

    child_processIssues and PRs related to the child_process subsystem.promisesIssues and PRs related to ECMAScript promises.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions