[react-packager] Use actual error types

Summary:
@public
Previously, we had to use errors as a property on the result object because there was no way to pass custom props between
the child worker and the parent. This has been fixed in node-worker-farm (D2092153) and now we can use regular errors.
This also adapts the transformer to babel-specific errors. Generic errors, however, should still work and render readable
info.

Additionally, I deprecated, but maintained backwards compatiblity for people in OSS that are using custom transformers.

Test Plan:
1. `./runJestTests.sh`
2. `./runJestTests.sh PackagerIntegration`
3. open the playground app
4. Add a syntax error. Say `1=x` somewhere in the file
5. Reload and see error message 'SyntaxError <filename> description (line:col)'
6. Make sure that the stack trace is clickable and it attempts to open the editor to the location
This commit is contained in:
Amjad Masad 2015-05-22 10:17:43 -07:00
parent 39af67ece3
commit 61efe8a34b
2 changed files with 35 additions and 29 deletions

View File

@ -57,25 +57,34 @@ describe('Transformer', function() {
}); });
pit('should add file info to parse errors', function() { pit('should add file info to parse errors', function() {
var message = 'message';
var snippet = 'snippet';
require('fs').readFile.mockImpl(function(file, callback) { require('fs').readFile.mockImpl(function(file, callback) {
callback(null, 'var x;\nvar answer = 1 = x;'); callback(null, 'var x;\nvar answer = 1 = x;');
}); });
workers.mockImpl(function(data, callback) { workers.mockImpl(function(data, callback) {
var esprimaError = new Error('Error: Line 2: Invalid left-hand side in assignment'); var babelError = new SyntaxError(message);
esprimaError.description = 'Invalid left-hand side in assignment'; babelError.type = 'SyntaxError';
esprimaError.lineNumber = 2; babelError.description = message;
esprimaError.column = 15; babelError.loc = {
callback(null, {error: esprimaError}); line: 2,
column: 15,
};
babelError.codeFrame = snippet;
callback(babelError);
}); });
return new Transformer(OPTIONS).loadFileAndTransform('foo-file.js') return new Transformer(OPTIONS).loadFileAndTransform('foo-file.js')
.catch(function(error) { .catch(function(error) {
expect(error.type).toEqual('TransformError'); expect(error.type).toEqual('TransformError');
expect(error.snippet).toEqual([ expect(error.message).toBe('SyntaxError ' + message);
'var answer = 1 = x;', expect(error.lineNumber).toBe(2);
' ^', expect(error.column).toBe(15);
].join('\n')); expect(error.filename).toBe('foo-file.js');
expect(error.description).toBe(message);
expect(error.snippet).toBe(snippet);
}); });
}); });
}); });

View File

@ -99,7 +99,12 @@ Transformer.prototype.loadFileAndTransform = function(filePath) {
}).then( }).then(
function(res) { function(res) {
if (res.error) { if (res.error) {
throw formatError(res.error, filePath, sourceCode); console.warn(
'Error property on the result value form the transformer',
'module is deprecated and will be removed in future versions.',
'Please pass an error object as the first argument to the callback'
);
throw formatError(res.error, filePath);
} }
return new ModuleTransport({ return new ModuleTransport({
@ -110,6 +115,8 @@ Transformer.prototype.loadFileAndTransform = function(filePath) {
}); });
} }
); );
}).catch(function(err) {
throw formatError(err, filePath);
}); });
}); });
}; };
@ -118,8 +125,8 @@ function TransformError() {}
util.inherits(TransformError, SyntaxError); util.inherits(TransformError, SyntaxError);
function formatError(err, filename, source) { function formatError(err, filename, source) {
if (err.lineNumber && err.column) { if (err.loc) {
return formatEsprimaError(err, filename, source); return formatBabelError(err, filename, source);
} else { } else {
return formatGenericError(err, filename, source); return formatGenericError(err, filename, source);
} }
@ -136,26 +143,16 @@ function formatGenericError(err, filename) {
return error; return error;
} }
function formatEsprimaError(err, filename, source) { function formatBabelError(err, filename) {
var stack = err.stack.split('\n');
stack.shift();
var msg = 'TransformError: ' + err.description + ' ' + filename + ':' +
err.lineNumber + ':' + err.column;
var sourceLine = source.split('\n')[err.lineNumber - 1];
var snippet = sourceLine + '\n' + new Array(err.column - 1).join(' ') + '^';
stack.unshift(msg);
var error = new TransformError(); var error = new TransformError();
error.message = msg;
error.type = 'TransformError'; error.type = 'TransformError';
error.stack = stack.join('\n'); error.message = (err.type || error.type) + ' ' + err.message;
error.snippet = snippet; error.stack = err.stack;
error.snippet = err.codeFrame;
error.lineNumber = err.loc.line;
error.column = err.loc.column;
error.filename = filename; error.filename = filename;
error.lineNumber = err.lineNumber; error.description = err.message;
error.column = err.column;
error.description = err.description;
return error; return error;
} }