Fix RN redbox messages for syntax errors by including error messages in payload

Summary:
**Summary**
With RN 0.52, when there was a redbox due to a syntax error in a source file (with regular, non-delta bundler), the redbox would say just "No message provided". The JSON that Metro sent to RN did not include a "message" field because `JSON.stringify(error)` does not include `message`.

**Test Plan**
Add a syntax error to one of the files in RNTester's JS and load the RNTester app (from RN master). See that the redbox now says there was a transform error with the syntax error's location.

Also tested adding a syntax error with HMR enabled and saw that the error `message` field was set in the payload as expected.

Also added a Jest test to Server-test.js.
Closes https://github.com/facebook/metro/pull/124

Differential Revision: D6728310

Pulled By: rafeca

fbshipit-source-id: 9ee3c113767d8c2849bcaac0cb8a9cfa8f2760a6
This commit is contained in:
James Ide 2018-01-16 17:08:29 -08:00 committed by Facebook Github Bot
parent 3c3d95fb15
commit b7248380a6
5 changed files with 76 additions and 2 deletions

View File

@ -47,6 +47,7 @@
"mkdirp": "^0.5.1",
"request": "^2.79.0",
"rimraf": "^2.5.4",
"serialize-error": "^2.1.0",
"source-map": "^0.5.6",
"temp": "0.8.3",
"throat": "^4.1.0",

View File

@ -42,7 +42,7 @@ describe('HmrServer', () => {
return deltaBundlerMock;
},
};
getDeltaTransformerMock.reporterMock = {
reporterMock = {
update: jest.fn(),
};
@ -127,4 +127,46 @@ describe('HmrServer', () => {
done();
}, 30);
});
it('should return error messages when there is a transform error', async done => {
jest.useRealTimers();
const sendMessage = jest.fn();
await hmrServer.onClientConnect(
'/hot?bundleEntry=EntryPoint.js&platform=ios',
sendMessage,
);
deltaTransformerMock.getDelta.mockImplementation(async () => {
const transformError = new SyntaxError('test syntax error');
transformError.type = 'TransformError';
transformError.filename = 'EntryPoint.js';
transformError.lineNumber = 123;
throw transformError;
});
deltaTransformerMock.emit('change');
setTimeout(function() {
expect(JSON.parse(sendMessage.mock.calls[0][0])).toEqual({
type: 'update-start',
});
const sentErrorMessage = JSON.parse(sendMessage.mock.calls[1][0]);
expect(sentErrorMessage).toMatchObject({type: 'error'});
expect(sentErrorMessage.body).toMatchObject({
type: 'TransformError',
message: 'test syntax error',
errors: [
{
filename: 'EntryPoint.js',
lineNumber: 123,
},
],
});
expect(JSON.parse(sendMessage.mock.calls[2][0])).toEqual({
type: 'update-done',
});
done();
}, 30);
});
});

View File

@ -301,6 +301,31 @@ describe('processRequest', () => {
expect(response.body).toEqual('{"delta": "bundle"}');
});
});
it('should include the error message for transform errors', () => {
Serializers.deltaBundle.mockImplementation(async () => {
const transformError = new SyntaxError('test syntax error');
transformError.type = 'TransformError';
transformError.filename = 'testFile.js';
transformError.lineNumber = 123;
throw transformError;
});
return makeRequest(requestHandler, 'index.delta?platform=ios').then(
function(response) {
expect(() => JSON.parse(response.body)).not.toThrow();
const body = JSON.parse(response.body);
expect(body).toMatchObject({
type: 'TransformError',
message: 'test syntax error',
});
expect(body.errors).toContainEqual({
filename: 'testFile.js',
lineNumber: 123,
});
},
);
});
});
describe('/onchange endpoint', () => {

View File

@ -12,6 +12,8 @@
'use strict';
const serializeError = require('serialize-error');
const {
UnableToResolveError,
} = require('../node-haste/DependencyGraph/ModuleResolution');
@ -67,7 +69,7 @@ function formatBundlingError(
},
];
return error;
return serializeError(error);
} else {
return {
type: 'InternalError',

View File

@ -4869,6 +4869,10 @@ send@0.13.2:
range-parser "~1.0.3"
statuses "~1.2.1"
serialize-error@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a"
serve-favicon@~2.3.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.3.2.tgz#dd419e268de012ab72b319d337f2105013f9381f"