mirror of https://github.com/status-im/metro.git
[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:
parent
39af67ece3
commit
61efe8a34b
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue