Ionic-cli: [3.6] events.js:182 throw er; // Unhandled ‘error’ event

Created on 28 Jul 2017  Â·  21Comments  Â·  Source: ionic-team/ionic-cli

Soimething seems to have gone wrong with CLI 3.6 on Windows:

https://forum.ionicframework.com/t/error-like-shown-below-when-running-ionic-serve-command-in-cmd-prompt/99944
https://forum.ionicframework.com/t/ionic-cli-error-after-update/99986

D:\MyCloud\git\cow-v2>ionic info --verbose
[DEBUG] CLI flags: { interactive: true, confirm: false }
[DEBUG] { cwd: 'D:\\MyCloud\\git\\cow-v2', local: true, binPath:
        'C:\\Users\\Adrian\\AppData\\Roaming\\npm\\node_modules\\ionic\\bin\\ionic', libPath:
        'D:\\MyCloud\\git\\cow-v2\\node_modules\\ionic\\dist\\index.js' }
[DEBUG] Loading local plugin @ionic/cli-plugin-proxy
[DEBUG] Throwing PLUGIN_NOT_INSTALLED for local @ionic/cli-plugin-proxy
[DEBUG] Loading local plugin @ionic/cli-plugin-ionic-angular
[DEBUG] Getting plugin info for ionic
[DEBUG] Checking for latest plugin version of ionic@latest.
[DEBUG] Getting plugin info for @ionic/cli-plugin-ionic-angular
[DEBUG] Checking for latest plugin version of @ionic/cli-plugin-ionic-angular@latest.
[DEBUG] New daemon pid: 39216

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: spawn C:\Program Files\nodejs\node.exe ENOENT
    at notFoundError (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:11:11)
    at verifyENOENT (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:46:16)
    at ChildProcess.cp.emit (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:33:19)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)

https://forum.ionicframework.com/t/error-after-update-to-ionic-3-6/99967

[WARN] You are not in an Ionic project directory. Project context may be missing.

cli packages:

    @ionic/cli-utils  : 1.6.0 (C:\Users\HP\AppData\Roaming\npm\node_modules\ionic\node_modules\@ionic\cli-utils)
    ionic (Ionic CLI) : 3.6.0 (C:\Users\HP\AppData\Roaming\npm\node_modules\ionic)

System:

    Node : v8.1.2
    OS   : Windows 10
    npm  : 5.0.3
bug

Most helpful comment

npm i -D -E [email protected]

This solution works for me

All 21 comments

(Last one got it working)

I think I found the cause:

  1. ionic daemon passes process.argv[0] to cross-spawn with shell: true . process.argv[0] contains node's full path which contains spaces (C:\Program Files\nodejs\node.exe) .
  2. When cross-spawn is called with shell: true on node 6+, it passes the arguments directly to child_process.spawn without escaping the spaces in the command.
  3. child_process.spawn does not escape the spaces in the command name when passed to cmd.exe because it would break other things: nodejs/node#7367
  4. cmd.exe tries to execute 'C:\Program` and fails.

Removing the shell argument fixes it for me. It was added in this commit calling it better windows behavior.

@dwieeb : can you explain what did that fix? And could it be reverted?

Alternatively, should cross-spawn be changed to escape the command even if node supports shell: true natively?

I filed a bug with cross-spawn: IndigoUnited/node-cross-spawn#77

@imgx64 Thanks for debugging so thoroughly. I was testing this on windows and it seems shell: true was required to get the background process functionality to work. I'll test this further.

@imgx64 I've never been able to reproduce this issue, FYI. I am on Windows 10 using command prompt.

I used shell: true because if I don't, the daemon process isn't long-lasting. You can confirm this by running ionic --verbose commands, it will say "New daemon pid:" every time with shell: false.

Here are the args with shell: true, notice the double quotes around the paths:

spawnargs:
   [ 'C:\\WINDOWS\\system32\\cmd.exe',
     '/s',
     '/c',
     '"C:\\WINDOWS\\system32\\cmd.exe /s /c ""C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\dwieeb\\AppData\\Roaming\\npm\\node_modules\\ionic\\bin\\ionic" "daemon" "--verbose" "--no-interactive" "--log-timestamps" "--interval" "10"""' ],

@imgx64 If you find the daemon.js file in the @ionic/cli-utils npm package on your local machine, you can play with the cross-spawn options. Also console.log(p) like I did to see the spawn args.

It just seems like there's different behavior from machine to machine somehow.

@dwieeb For some inexplicable reason, the issue disappeared after deleting node_modules and running npm install again. I'm certain I tried that yesterday and it didn't work.

I did a little more investigation and found that [email protected] (required by @ionic/[email protected], which is required by [email protected]) quotes the command passed to shell correctly, but [email protected] (required by @ionic/[email protected]) does not quote it. Maybe there's a bug in npm which made @ionic/cli-utils import [email protected]? I really can't tell, and I'm unable to reproduce the issue anymore.

Try to install @ionic/cli-utils, this fixed the issue for me.
npm install @ionic/cli-utils

@imgx64 Very frustrating! That gives me a lot more to work with, though. I will debug this tonight when I have access to Windows again. Thanks so much for working with me on this 🎉

@imgx64 Not able to reproduce with cross-spawn 4 _or_ 5. It puts double quotes around each argument in both versions, at least for me.

@dwieeb What does the below output?

mkdir test
cd test
npm init --yes
npm install [email protected]
node
> require('cross-spawn').spawn('C:\\Program Files\\nodejs\\node.exe', [], {shell:true})

@imgx64 For me, I also have the original problem sometimes now, this returns:

PS C:\Users\Jan\Documents\test> node
> require('cross-spawn').spawn('C:\\Program Files\\nodejs\\node.exe', [], {shell:true})
ChildProcess {
  domain:
   Domain {
     domain: null,
     _events: { error: [Function: debugDomainError] },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [] },
  _events: {},
  _eventsCount: 0,
  _maxListeners: undefined,
  _closesNeeded: 3,
  _closesGot: 0,
  connected: false,
  signalCode: null,
  exitCode: null,
  killed: false,
  spawnfile: 'C:\\WINDOWS\\system32\\cmd.exe',
  _handle: Process { owner: [Circular], onexit: [Function], pid: 17796 },
  spawnargs:
   [ 'C:\\WINDOWS\\system32\\cmd.exe',
     '/d',
     '/s',
     '/c',
     '"C:\\Program Files\\nodejs\\node.exe"' ],
  pid: 17796,
  stdin:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      Pipe {
        bytesRead: 0,
        _externalStream: [External],
        fd: -1,
        writeQueueSize: 0,
        owner: [Circular],
        onread: [Function: onread],
        reading: true },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: null,
        ended: false,
        endEmitted: false,
        reading: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     domain:
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [] },
     _events:
      { end: [Object],
        finish: [Function: onSocketFinish],
        _socketEnd: [Function: onSocketEnd] },
     _eventsCount: 3,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: false,
     _bytesDispatched: 0,
     _sockname: null,
     _writev: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     [Symbol(asyncId)]: 109,
     [Symbol(bytesRead)]: 0 },
  stdout:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      Pipe {
        bytesRead: 0,
        _externalStream: [External],
        fd: -1,
        writeQueueSize: 0,
        owner: [Circular],
        onread: [Function: onread],
        reading: true },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: null,
        ended: false,
        endEmitted: false,
        reading: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     domain:
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [] },
     _events:
      { end: [Object],
        finish: [Function: onSocketFinish],
        _socketEnd: [Function: onSocketEnd],
        close: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: false,
     allowHalfOpen: false,
     _bytesDispatched: 0,
     _sockname: null,
     _writev: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     [Symbol(asyncId)]: 110,
     [Symbol(bytesRead)]: 0 },
  stderr:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      Pipe {
        bytesRead: 0,
        _externalStream: [External],
        fd: -1,
        writeQueueSize: 0,
        owner: [Circular],
        onread: [Function: onread],
        reading: true },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: null,
        ended: false,
        endEmitted: false,
        reading: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     domain:
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [] },
     _events:
      { end: [Object],
        finish: [Function: onSocketFinish],
        _socketEnd: [Function: onSocketEnd],
        close: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: false,
     allowHalfOpen: false,
     _bytesDispatched: 0,
     _sockname: null,
     _writev: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     [Symbol(asyncId)]: 111,
     [Symbol(bytesRead)]: 0 },
  stdio:
   [ Socket {
       connecting: false,
       _hadError: false,
       _handle: [Object],
       _parent: null,
       _host: null,
       _readableState: [Object],
       readable: false,
       domain: [Object],
       _events: [Object],
       _eventsCount: 3,
       _maxListeners: undefined,
       _writableState: [Object],
       writable: true,
       allowHalfOpen: false,
       _bytesDispatched: 0,
       _sockname: null,
       _writev: null,
       _pendingData: null,
       _pendingEncoding: '',
       server: null,
       _server: null,
       [Symbol(asyncId)]: 109,
       [Symbol(bytesRead)]: 0 },
     Socket {
       connecting: false,
       _hadError: false,
       _handle: [Object],
       _parent: null,
       _host: null,
       _readableState: [Object],
       readable: true,
       domain: [Object],
       _events: [Object],
       _eventsCount: 4,
       _maxListeners: undefined,
       _writableState: [Object],
       writable: false,
       allowHalfOpen: false,
       _bytesDispatched: 0,
       _sockname: null,
       _writev: null,
       _pendingData: null,
       _pendingEncoding: '',
       server: null,
       _server: null,
       [Symbol(asyncId)]: 110,
       [Symbol(bytesRead)]: 0 },
     Socket {
       connecting: false,
       _hadError: false,
       _handle: [Object],
       _parent: null,
       _host: null,
       _readableState: [Object],
       readable: true,
       domain: [Object],
       _events: [Object],
       _eventsCount: 4,
       _maxListeners: undefined,
       _writableState: [Object],
       writable: false,
       allowHalfOpen: false,
       _bytesDispatched: 0,
       _sockname: null,
       _writev: null,
       _pendingData: null,
       _pendingEncoding: '',
       server: null,
       _server: null,
       [Symbol(asyncId)]: 111,
       [Symbol(bytesRead)]: 0 } ],
  emit: [Function] }
> Error: spawn C:\Program Files\nodejs\node.exe ENOENT
    at notFoundError (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:11:11)
    at verifyENOENT (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:46:16)
    at ChildProcess.cp.emit (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:33:19)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
>

@janpio
Yeah, that's what I get too. I was wondering if it works on @dwieeb 's machine.

If you can reproduce the original issue (throw er; // Unhandled ‘error’ event), please run npm ls cross-spawn on the same project.

Sure:

PS C:\Users\Jan\Documents\stromzaehler> ionic info
\ Gathering environment info
events.js:182
      throw er; // Unhandled 'error' event
      ^

Error: spawn C:\Program Files\nodejs\node.exe ENOENT
    at notFoundError (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:11:11)
    at verifyENOENT (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:46:16)
    at ChildProcess.cp.emit (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:33:19)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
PS C:\Users\Jan\Documents\stromzaehler> npm ls cross-spawn
ionic-hello-world@ C:\Users\Jan\Documents\stromzaehler
+-- @ionic/[email protected]
| +-- [email protected]
| `-- [email protected]
|   `-- [email protected]
+-- @ionic/[email protected]
| +-- @ionic/[email protected]
| | `-- UNMET DEPENDENCY cross-spawn@^4.0.2
| `-- [email protected]  extraneous
+-- @ionic/[email protected]
| `-- [email protected]  extraneous
`-- [email protected]
  `-- [email protected]  extraneous

npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\@ionic\cli-plugin-cordova\node_m
odules\cross-spawn
npm ERR! missing: cross-spawn@^4.0.2, required by @ionic/[email protected]
npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\@ionic\cli-plugin-ionic-angular\
node_modules\cross-spawn
npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\ionic\node_modules\cross-spawn
PS C:\Users\Jan\Documents\stromzaehler>

And so the pretty colors don't get lost:
image

What @rluckez wrote actually worked for me as well, by the way:

Try to install @ionic/cli-utils, this fixed the issue for me.
npm install @ionic/cli-utils

Interesting. cross-spawn@^4.0.2 was listed as an "UNMET DEPENDENCY" in @janpio's node_modules. It seems this is an npm bug as well? It failed to install the appropriate version for @ionic/cli-utils.

So @imgx64, after using cross-spawn 5 ...

On Windows,

  1. Using detached: true, shell: true, node exits silently with exit code 1.
  2. Using detached: true, shell: false, things behave as expected, except child processes of the daemon process (the npm info commands) get spun up into a dozen cmd.exe windows... very unsightly. For some reason, even with shell: false on these subcommands (see https://github.com/ionic-team/ionic-cli/blob/master/packages/cli-utils/src/lib/utils/shell.ts#L31), the spawnargs contain cmd.exe:
```
  spawnargs:
   [ 'C:\\WINDOWS\\system32\\cmd.exe',
     '/d',
     '/s',
     '/c',
     '"npm "view" "ionic" "dist-tags.latest" "--json""' ],
```

  1. Using detached: false of course kills the child process when the parent process has completed.

Since option 2 seems to be what we want, I could do HTTP requests to the npm registry instead of using child processes in the daemon process.

According to this comment I _should_ be using shell: true and putting quotes around the path.

So I think the best course of action is to use cross-spawn 5, and use:

crossSpawn.spawn(`"${process.execPath}"`, [process.argv[1], 'daemon', ...]

I tested this with detached: false, which apparently we _do_ want for subprocesses using shell in Windows. It finally works as I expect.

npm i -D -E [email protected]

This solution works for me

npm i -D -E [email protected]

This solution works for me.
thank you @zurich316

We must be getting a bunch of people from Google regarding that websocket issue, as ws has nothing to do with the original issue, though the error is similar.

For the websocket issue:

  • If you're using Ionic Angular, install the latest @ionic/app-scripts, which has ws pinned. You do not need to install it yourself. (the commit for this fix is here https://github.com/ionic-team/ionic-app-scripts/commit/db0cc4de9194bbf9b825c4934ea48a7510a9f5fb)
  • If you're using Ionic 1, the best fix is to install ws yourself at 3.3.2 for now. (npm i -D -E [email protected])
Was this page helpful?
0 / 5 - 0 ratings