[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 6cb31bb19d
commit bd11de1b51
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() {
var message = 'message';
var snippet = 'snippet';
require('fs').readFile.mockImpl(function(file, callback) {
callback(null, 'var x;\nvar answer = 1 = x;');
});
workers.mockImpl(function(data, callback) {
var esprimaError = new Error('Error: Line 2: Invalid left-hand side in assignment');
esprimaError.description = 'Invalid left-hand side in assignment';
esprimaError.lineNumber = 2;
esprimaError.column = 15;
callback(null, {error: esprimaError});
var babelError = new SyntaxError(message);
babelError.type = 'SyntaxError';
babelError.description = message;
babelError.loc = {
line: 2,
column: 15,
};
babelError.codeFrame = snippet;
callback(babelError);
});
return new Transformer(OPTIONS).loadFileAndTransform('foo-file.js')
.catch(function(error) {
expect(error.type).toEqual('TransformError');
expect(error.snippet).toEqual([
'var answer = 1 = x;',
' ^',
].join('\n'));
expect(error.message).toBe('SyntaxError ' + message);
expect(error.lineNumber).toBe(2);
expect(error.column).toBe(15);
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(
function(res) {
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({
@ -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);
function formatError(err, filename, source) {
if (err.lineNumber && err.column) {
return formatEsprimaError(err, filename, source);
if (err.loc) {
return formatBabelError(err, filename, source);
} else {
return formatGenericError(err, filename, source);
}
@ -136,26 +143,16 @@ function formatGenericError(err, filename) {
return error;
}
function formatEsprimaError(err, filename, source) {
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);
function formatBabelError(err, filename) {
var error = new TransformError();
error.message = msg;
error.type = 'TransformError';
error.stack = stack.join('\n');
error.snippet = snippet;
error.message = (err.type || error.type) + ' ' + err.message;
error.stack = err.stack;
error.snippet = err.codeFrame;
error.lineNumber = err.loc.line;
error.column = err.loc.column;
error.filename = filename;
error.lineNumber = err.lineNumber;
error.column = err.column;
error.description = err.description;
error.description = err.message;
return error;
}