Skip to content

subprocess.stdout can be undefined instead of null #43905

Closed
@unarist

Description

@unarist

Affected URL(s)

https://nodejs.org/docs/latest-v16.x/api/child_process.html#subprocessstdout

Description of the problem

The subprocess.stdout property can be null if the child process could not be successfully spawned.

However, it can be undefined in some cases:

$ docker run --rm -it node:16 /bin/bash
root@c12d92a299db:/# ulimit -n 17
root@c12d92a299db:/# node -e 'p=require("child_process").spawn("uname");p.stdout.on("data",console.log)'
[eval]:1
p=require("child_process").spawn("uname");p.stdout.on("data",console.log)
                                                   ^

TypeError: Cannot read properties of undefined (reading 'on')
    at [eval]:1:52
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:305:38)
    at node:internal/process/execution:76:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:75:60)
    at node:internal/main/eval_string:27:3
root@c12d92a299db:/# node -e 'console.log(require("child_process").spawn("uname"))'
<ref *1> ChildProcess {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  _closesNeeded: 1,
  _closesGot: 0,
  connected: false,
  signalCode: null,
  exitCode: null,
  killed: false,
  spawnfile: 'uname',
  _handle: Process {
    onexit: [Function (anonymous)],
    [Symbol(owner_symbol)]: [Circular *1]
  },
  spawnargs: [ 'uname' ],
  [Symbol(kCapture)]: false
}
node:events:505
      throw er; // Unhandled 'error' event
      ^

Error: spawn uname EMFILE
    at Process.ChildProcess._handle.onexit (node:internal/child_process:283:19)
    at onErrorNT (node:internal/child_process:478:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (node:internal/child_process:289:12)
    at onErrorNT (node:internal/child_process:478:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -24,
  code: 'EMFILE',
  syscall: 'spawn uname',
  path: 'uname',
  spawnargs: []
}

I think this should be documented.

Activity

added
docIssues and PRs related to the documentations.
on Jul 20, 2022
cola119

cola119 commented on Jul 20, 2022

@cola119
Member

This is because ChildProcess.prototype.spawn returns the error before ChildProcess.stdout is initialized to null at L457.

const err = this._handle.spawn(options);
// Run-time errors should emit an error, not throw an exception.
if (err === UV_EACCES ||
err === UV_EAGAIN ||
err === UV_EMFILE ||
err === UV_ENFILE ||
err === UV_ENOENT) {
process.nextTick(onErrorNT, this, err);
// There is no point in continuing when we've hit EMFILE or ENFILE
// because we won't be able to set up the stdio file descriptors.
if (err === UV_EMFILE || err === UV_ENFILE)
return err;

Which is better to document it can be null and undefined, or to fix to initialize ChildProcess.stdout to null as an initial value at the top of the function?

unarist

unarist commented on Jul 21, 2022

@unarist
Author

I think it would be better if stdout has same value when the spawn can't create pipes, for consistency and maybe ease to handle.

I'm okay for documenting the behavior, though.

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.docIssues and PRs related to the documentations.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Participants

    @unarist@cola119@VoltrexKeyva

    Issue actions

      `subprocess.stdout` can be undefined instead of null · Issue #43905 · nodejs/node