Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

CI build does not bail with proper exit code #133

Closed
AndyOGo opened this issue Feb 17, 2017 · 11 comments
Closed

CI build does not bail with proper exit code #133

AndyOGo opened this issue Feb 17, 2017 · 11 comments

Comments

@AndyOGo
Copy link

AndyOGo commented Feb 17, 2017

HappyPack causes my CI build to hang on error (it seems active pipe are lying around), instead it should bail properly with a non zero exit code as defined by webpacks --bail option.

If I disable HappyPack, webpack exits properly with non zero exit code.

clean-webpack-plugin: frontend-lib/dist/js has been removed.
ModuleNotFoundError: Module not found: Error: Cannot resolve module 'module-not-found' in frontend-lib/src/js
    at frontend-lib/node_modules/webpack/lib/Compilation.js:229:38
    at onDoneResolving (frontend-lib/node_modules/webpack/lib/NormalModuleFactory.js:29:20)
    at frontend-lib/node_modules/webpack/lib/NormalModuleFactory.js:85:20
    at frontend-lib/node_modules/async/lib/async.js:726:13
    at frontend-lib/node_modules/async/lib/async.js:52:16
    at done (frontend-lib/node_modules/async/lib/async.js:241:17)
    at frontend-lib/node_modules/async/lib/async.js:44:16
    at frontend-lib/node_modules/async/lib/async.js:723:17
    at frontend-lib/node_modules/async/lib/async.js:167:37
    at frontend-lib/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:24:19
    at onResolved (frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:38:18)
    at innerCallback (frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:94:11)
    at loggingCallbackWrapper (frontend-lib/node_modules/enhanced-resolve/lib/createInnerCallback.js:21:19)
    at frontend-lib/node_modules/tapable/lib/Tapable.js:134:6
    at frontend-lib/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js:54:23
    at frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:191:15
    at frontend-lib/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js:45:26
    at loggingCallbackWrapper (frontend-lib/node_modules/enhanced-resolve/lib/createInnerCallback.js:21:19)
    at frontend-lib/node_modules/tapable/lib/Tapable.js:134:6
    at frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:122:33
    at frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:191:15
    at applyPluginsParallelBailResult.createInnerCallback.log (frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:110:4)
    at loggingCallbackWrapper (frontend-lib/node_modules/enhanced-resolve/lib/createInnerCallback.js:21:19)
    at frontend-lib/node_modules/tapable/lib/Tapable.js:134:6
    at Tapable.<anonymous> (frontend-lib/node_modules/enhanced-resolve/lib/FileAppendPlugin.js:31:26)
    at frontend-lib/node_modules/enhanced-resolve/lib/Resolver.js:191:15
    at frontend-lib/node_modules/enhanced-resolve/lib/FileAppendPlugin.js:28:12
    at Storage.finished (frontend-lib/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:38:16)
    at frontend-lib/node_modules/graceful-fs/polyfills.js:284:29
    at FSReqWrap.oncomplete (fs.js:82:15)
resolve module module-not-found in frontend-lib/src/js
  looking for modules in frontend-lib/src
    frontend-lib/src/module-not-found doesn't exist (module as directory)
    resolve 'file' module-not-found in frontend-lib/src
      resolve file
        frontend-lib/src/module-not-found doesn't exist
        frontend-lib/src/module-not-found.js doesn't exist
        frontend-lib/src/module-not-found.jsx doesn't exist
  looking for modules in frontend-lib/node_modules
    frontend-lib/node_modules/module-not-found doesn't exist (module as directory)
    resolve 'file' module-not-found in frontend-lib/node_modules
      resolve file
        frontend-lib/node_modules/module-not-found doesn't exist
        frontend-lib/node_modules/module-not-found.js doesn't exist
        frontend-lib/node_modules/module-not-found.jsx doesn't exist
  looking for modules in frontend-lib/node_modules
    frontend-lib/node_modules/module-not-found doesn't exist (module as directory)
    resolve 'file' module-not-found in frontend-lib/node_modules
      resolve file
        frontend-lib/node_modules/module-not-found doesn't exist
        frontend-lib/node_modules/module-not-found.js doesn't exist
        frontend-lib/node_modules/module-not-found.jsx doesn't exist
[ WriteStream {
    _connecting: false,
    _hadError: false,
    _handle:
     TTY {
       _externalStream: {},
       fd: 12,
       writeQueueSize: 0,
       owner: [Circular],
       onread: [Function: onread] },
    _parent: null,
    _host: null,
    _readableState:
     ReadableState {
       objectMode: false,
       highWaterMark: 16384,
       buffer: [],
       length: 0,
       pipes: null,
       pipesCount: 0,
       flowing: null,
       ended: false,
       endEmitted: false,
       reading: false,
       sync: true,
       needReadable: false,
       emittedReadable: false,
       readableListening: false,
       resumeScheduled: false,
       defaultEncoding: 'utf8',
       ranOut: false,
       awaitDrain: 0,
       readingMore: false,
       decoder: null,
       encoding: null },
    readable: false,
    domain: null,
    _events:
     { end: [Object],
       finish: [Function: onSocketFinish],
       _socketEnd: [Function: onSocketEnd] },
    _eventsCount: 3,
    _maxListeners: undefined,
    _writableState:
     WritableState {
       objectMode: false,
       highWaterMark: 16384,
       needDrain: false,
       ending: false,
       ended: false,
       finished: false,
       decodeStrings: false,
       defaultEncoding: 'utf8',
       length: 0,
       writing: false,
       corked: 0,
       sync: false,
       bufferProcessing: false,
       onwrite: [Function],
       writecb: null,
       writelen: 0,
       bufferedRequest: null,
       lastBufferedRequest: null,
       pendingcb: 0,
       prefinished: false,
       errorEmitted: false,
       bufferedRequestCount: 0,
       corkedRequestsFree: [Object] },
    writable: true,
    allowHalfOpen: false,
    destroyed: false,
    bytesRead: 0,
    _bytesDispatched: 5496,
    _sockname: null,
    _writev: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    columns: 202,
    rows: 22,
    _type: 'tty',
    fd: 2,
    _isStdio: true,
    destroySoon: [Function],
    destroy: [Function] },
  WriteStream {
    _connecting: false,
    _hadError: false,
    _handle:
     TTY {
       _externalStream: {},
       fd: 19,
       writeQueueSize: 0,
       owner: [Circular],
       onread: [Function: onread] },
    _parent: null,
    _host: null,
    _readableState:
     ReadableState {
       objectMode: false,
       highWaterMark: 16384,
       buffer: [],
       length: 0,
       pipes: null,
       pipesCount: 0,
       flowing: null,
       ended: false,
       endEmitted: false,
       reading: false,
       sync: true,
       needReadable: false,
       emittedReadable: false,
       readableListening: false,
       resumeScheduled: false,
       defaultEncoding: 'utf8',
       ranOut: false,
       awaitDrain: 0,
       readingMore: false,
       decoder: null,
       encoding: null },
    readable: false,
    domain: null,
    _events:
     { end: [Object],
       finish: [Function: onSocketFinish],
       _socketEnd: [Function: onSocketEnd] },
    _eventsCount: 3,
    _maxListeners: undefined,
    _writableState:
     WritableState {
       objectMode: false,
       highWaterMark: 16384,
       needDrain: false,
       ending: false,
       ended: false,
       finished: false,
       decodeStrings: false,
       defaultEncoding: 'utf8',
       length: 0,
       writing: false,
       corked: 0,
       sync: false,
       bufferProcessing: false,
       onwrite: [Function],
       writecb: null,
       writelen: 0,
       bufferedRequest: null,
       lastBufferedRequest: null,
       pendingcb: 3,
       prefinished: false,
       errorEmitted: false,
       bufferedRequestCount: 0,
       corkedRequestsFree: [Object] },
    writable: true,
    allowHalfOpen: false,
    destroyed: false,
    bytesRead: 0,
    _bytesDispatched: 2191,
    _sockname: null,
    _writev: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    columns: 202,
    rows: 22,
    _type: 'tty',
    fd: 1,
    _isStdio: true,
    destroySoon: [Function],
    destroy: [Function] },
  Timer {
    '0': [Function: listOnTimeout],
    _list:
     TimersList {
       _idleNext: [Circular],
       _idlePrev: [Circular],
       _timer: [Circular],
       _unrefed: false,
       msecs: 5000 } },
  ChildProcess {
    domain: null,
    _events:
     { internalMessage: [Function],
       error: [Function: throwError],
       exit: [Function],
       message: [Object] },
    _eventsCount: 4,
    _maxListeners: undefined,
    _closesNeeded: 2,
    _closesGot: 0,
    connected: true,
    signalCode: null,
    exitCode: null,
    killed: false,
    spawnfile: '/.nvm/versions/node/v5.10.1/bin/node',
    _handle: Process { owner: [Circular], onexit: [Function], pid: 5744 },
    spawnargs:
     [ '/.nvm/versions/node/v5.10.1/bin/node',
       'frontend-lib/node_modules/happypack/lib/HappyWorkerChannel.js',
       0 ],
    pid: 5744,
    stdin: null,
    stdout: null,
    stderr: null,
    stdio: [ null, null, null, null ],
    _channel:
     Pipe {
       _externalStream: {},
       fd: 21,
       writeQueueSize: 0,
       buffering: false,
       onread: [Function],
       sockets: [Object] },
    _handleQueue: null,
    send: [Function],
    _send: [Function],
    disconnect: [Function],
    _disconnect: [Function] },
  Pipe {
    _externalStream: {},
    fd: 21,
    writeQueueSize: 0,
    buffering: false,
    onread: [Function],
    sockets: { got: {}, send: {} } },
  ChildProcess {
    domain: null,
    _events:
     { internalMessage: [Function],
       error: [Function: throwError],
       exit: [Function],
       message: [Object] },
    _eventsCount: 4,
    _maxListeners: undefined,
    _closesNeeded: 2,
    _closesGot: 0,
    connected: true,
    signalCode: null,
    exitCode: null,
    killed: false,
    spawnfile: '/.nvm/versions/node/v5.10.1/bin/node',
    _handle: Process { owner: [Circular], onexit: [Function], pid: 5745 },
    spawnargs:
     [ '/.nvm/versions/node/v5.10.1/bin/node',
       'frontend-lib/node_modules/happypack/lib/HappyWorkerChannel.js',
       1 ],
    pid: 5745,
    stdin: null,
    stdout: null,
    stderr: null,
    stdio: [ null, null, null, null ],
    _channel:
     Pipe {
       _externalStream: {},
       fd: 22,
       writeQueueSize: 0,
       buffering: false,
       onread: [Function],
       sockets: [Object] },
    _handleQueue: null,
    send: [Function],
    _send: [Function],
    disconnect: [Function],
    _disconnect: [Function] },
  Pipe {
    _externalStream: {},
    fd: 22,
    writeQueueSize: 0,
    buffering: false,
    onread: [Function],
    sockets: { got: {}, send: {} } },
  ChildProcess {
    domain: null,
    _events:
     { internalMessage: [Function],
       error: [Function: throwError],
       exit: [Function],
       message: [Object] },
    _eventsCount: 4,
    _maxListeners: undefined,
    _closesNeeded: 2,
    _closesGot: 0,
    connected: true,
    signalCode: null,
    exitCode: null,
    killed: false,
    spawnfile: '/.nvm/versions/node/v5.10.1/bin/node',
    _handle: Process { owner: [Circular], onexit: [Function], pid: 5746 },
    spawnargs:
     [ '/.nvm/versions/node/v5.10.1/bin/node',
       'frontend-lib/node_modules/happypack/lib/HappyWorkerChannel.js',
       2 ],
    pid: 5746,
    stdin: null,
    stdout: null,
    stderr: null,
    stdio: [ null, null, null, null ],
    _channel:
     Pipe {
       _externalStream: {},
       fd: 23,
       writeQueueSize: 0,
       buffering: false,
       onread: [Function],
       sockets: [Object] },
    _handleQueue: null,
    send: [Function],
    _send: [Function],
    disconnect: [Function],
    _disconnect: [Function] },
  Pipe {
    _externalStream: {},
    fd: 23,
    writeQueueSize: 0,
    buffering: false,
    onread: [Function],
    sockets: { got: {}, send: {} } },
  ChildProcess {
    domain: null,
    _events:
     { internalMessage: [Function],
       error: [Function: throwError],
       exit: [Function],
       message: [Object] },
    _eventsCount: 4,
    _maxListeners: undefined,
    _closesNeeded: 2,
    _closesGot: 0,
    connected: true,
    signalCode: null,
    exitCode: null,
    killed: false,
    spawnfile: '/.nvm/versions/node/v5.10.1/bin/node',
    _handle: Process { owner: [Circular], onexit: [Function], pid: 5747 },
    spawnargs:
     [ '/.nvm/versions/node/v5.10.1/bin/node',
       'frontend-lib/node_modules/happypack/lib/HappyWorkerChannel.js',
       3 ],
    pid: 5747,
    stdin: null,
    stdout: null,
    stderr: null,
    stdio: [ null, null, null, null ],
    _channel:
     Pipe {
       _externalStream: {},
       fd: 24,
       writeQueueSize: 0,
       buffering: false,
       onread: [Function],
       sockets: [Object] },
    _handleQueue: null,
    send: [Function],
    _send: [Function],
    disconnect: [Function],
    _disconnect: [Function] },
  Pipe {
    _externalStream: {},
    fd: 24,
    writeQueueSize: 0,
    buffering: false,
    onread: [Function],
    sockets: { got: {}, send: {} } } ]
@amireh
Copy link
Owner

amireh commented Feb 17, 2017

This is a duplicate of #19 - I can't see a fix on happypack's end (at least for webpack 1, didn't check for webpack 2.)

Can you try using the NoErrors plugin without the bail option? Wouldn't that result in the same behaviour?

@AndyOGo
Copy link
Author

AndyOGo commented Feb 17, 2017

@amireh
Thanks for your quick reply.
Well the NoErrorsPlugin does not what it's name suggest. It just avoids to emit assets which errored. More info here.

All loaders, plugins, etc. can report errors to webpack. As described here:

this.callback(err, values...) function. Errors are passed to the this.callback function or thrown in a sync loader.

IMHO I'm really sure that this is an issue on HappyPack's side.
Because any other loader I use, properly bails on error with --bail enabled.
So may I ask you to look into this?

@AndyOGo
Copy link
Author

AndyOGo commented Feb 17, 2017

Meanwhile the quickfix is to simply disable happypack for production builds, unfotunately.

@amireh
Copy link
Owner

amireh commented Feb 17, 2017

IMHO I'm really sure that this is an issue on HappyPack's side.

It both is and isn't: webpack isn't emitting the signal when it should, so happypack has no means to clean up in a --bail build. So what I'm saying is that it can't be fixed by HappyPack's code alone.

@AndyOGo
Copy link
Author

AndyOGo commented Feb 17, 2017

I see your point.
Though I'm sure it can be handled within Happypack, even if that means it needs it's own --bail option. Still better to have it working.

@amireh
Copy link
Owner

amireh commented Aug 18, 2017

I've revisited this for our own CI and it still can't be fixed on happypack's side. Webpack (1 at least) fails to emit any kind of signal when --bail is engaged and there's no way for happypack to clean itself up on error.

Closing as can't fix.

@amireh
Copy link
Owner

amireh commented Aug 18, 2017

Here's a variant of the fix we've applied: since it's not possible to get at the errors from the plugin/loader layer during bail, you need to invoke webpack using the node API and register a callback that will exit the process correctly:

#!/usr/bin/env node

// @file: bailing-webpack.js

var webpack = require('webpack');
var path = require('path')
var config = require(path.resolve(process.argv[2]))

webpack(config, function(err, rawStats) {
  if (err) {
    console.error(err.stack);
    process.exit(1);
  }
  else {
    var stats = rawStats.toJson();

    if (stats.errors.length > 0) {
      stats.errors.forEach(function(moduleErr) {
        console.error(moduleErr.stack);
      })

      process.exit(1);
    }
    else {
      process.exit(0);
    }
  }
})

The downside here is that you're no longer using the webpack CLI so you can't pass in command line arguments (unless you wrap them yourself) but it shouldn't be much of a problem for CI builds.

@amireh
Copy link
Owner

amireh commented Aug 18, 2017

I have also just verified that --bail works as expected in both webpack 2 and 3.

@AndyOGo
Copy link
Author

AndyOGo commented Aug 18, 2017

@amireh
Thank you so much for looking into this.
I guess updating webpack is the best choice then

@amireh
Copy link
Owner

amireh commented Aug 18, 2017

No problem!

I'll see if I get time to submit a PR to webpack 1 and apply a real fix, then we won't need to do anything. But not sure if they're still maintaining that branch (or accepting PRs for it.)

@AndyOGo
Copy link
Author

AndyOGo commented Aug 18, 2017

@amireh
That would be amazing for all webpack 1 users 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants