diff --git a/react-packager/src/JSTransformer/index.js b/react-packager/src/JSTransformer/index.js index 93dd5d01..9bf19139 100644 --- a/react-packager/src/JSTransformer/index.js +++ b/react-packager/src/JSTransformer/index.js @@ -25,6 +25,9 @@ const MAX_CALLS_PER_WORKER = 600; // Worker will timeout if one of the callers timeout. const DEFAULT_MAX_CALL_TIME = 120000; +// How may times can we tolerate failures from the worker. +const MAX_RETRIES = 3; + const validateOpts = declareOpts({ projectRoots: { type: 'array', @@ -63,6 +66,7 @@ class Transformer { maxConcurrentCallsPerWorker: 1, maxCallsPerWorker: MAX_CALLS_PER_WORKER, maxCallTime: opts.transformTimeoutInterval, + maxRetries: MAX_RETRIES, }, opts.transformModulePath); this._transform = Promise.denodeify(this._workers); @@ -118,6 +122,13 @@ class Transformer { ); timeoutErr.type = 'TimeoutError'; throw timeoutErr; + } else if (err.type === 'ProcessTerminatedError') { + const uncaughtError = new Error( + 'Uncaught error in the transformer worker: ' + + this._opts.transformModulePath + ); + uncaughtError.type = 'ProcessTerminatedError'; + throw uncaughtError; } throw formatError(err, filePath); diff --git a/react-packager/src/SocketInterface/SocketClient.js b/react-packager/src/SocketInterface/SocketClient.js index 30b599b0..e20e5b89 100644 --- a/react-packager/src/SocketInterface/SocketClient.js +++ b/react-packager/src/SocketInterface/SocketClient.js @@ -13,6 +13,10 @@ const Promise = require('promise'); const bser = require('bser'); const debug = require('debug')('ReactPackager:SocketClient'); const net = require('net'); +const path = require('path'); +const tmpdir = require('os').tmpdir(); + +const LOG_PATH = path.join(tmpdir, 'react-packager.log'); class SocketClient { static create(sockPath) { @@ -81,7 +85,9 @@ class SocketClient { delete this._resolvers[message.id]; if (message.type === 'error') { - resolver.reject(new Error(message.data)); + resolver.reject(new Error( + message.data + '\n' + 'See logs ' + LOG_PATH + )); } else { resolver.resolve(message.data); } diff --git a/react-packager/src/SocketInterface/SocketServer.js b/react-packager/src/SocketInterface/SocketServer.js index 2e91aaba..d3cb752d 100644 --- a/react-packager/src/SocketInterface/SocketServer.js +++ b/react-packager/src/SocketInterface/SocketServer.js @@ -71,6 +71,11 @@ class SocketServer { debug('request error', error); this._jobs--; this._reply(sock, m.id, 'error', error.stack); + + // Fatal error from JSTransformer transform workers. + if (error.type === 'ProcessTerminatedError') { + setImmediate(() => process.exit(1)); + } }; switch (m.type) {