Skip to content

Commit 8bc02fd

Browse files
motiz88facebook-github-bot
authored andcommitted
Remove framesToPop support from ExceptionsManager and parseErrorStack
Summary: Removes support for the non-standard `framesToPop` error property from React Native. Redboxes will now ignore this field. The way to skip uninformative frames in stack traces going forward is to use Metro's `customizeFrame` config option, for which the React Native CLI ships useful defaults (see: react-native-community/cli#596, react-native-community/cli#780) Changelog: [General] [Removed] - Remove support for framesToPop from ExceptionsManager Reviewed By: rickhanlonii Differential Revision: D17877444 fbshipit-source-id: 04aa332c45ad35a99ae20e05fb87b34c91a557ab
1 parent def3ebe commit 8bc02fd

File tree

4 files changed

+19
-23
lines changed

4 files changed

+19
-23
lines changed

Libraries/Core/Devtools/__tests__/parseErrorStack-test.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,15 @@ describe('parseErrorStack', function() {
2626
expect(firstFrame.file).toMatch(/parseErrorStack-test\.js$/);
2727
});
2828

29-
it('supports framesToPop', function() {
29+
it('does not support framesToPop', function() {
3030
function getWrappedError() {
3131
const error = getFakeError();
3232
error.framesToPop = 1;
3333
return error;
3434
}
3535

36-
// Make sure framesToPop == 1 causes it to ignore getFakeError
37-
// stack frame
3836
const stack = parseErrorStack(getWrappedError());
39-
expect(stack[0].methodName).toEqual('getWrappedError');
37+
expect(stack[0].methodName).toEqual('getFakeError');
4038
});
4139

4240
it('ignores bad inputs', function() {

Libraries/Core/Devtools/parseErrorStack.js

-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import type {StackFrame} from '../NativeExceptionsManager';
1414

1515
export type ExtendedError = Error & {
16-
framesToPop?: number,
1716
jsEngine?: string,
1817
preventSymbolication?: boolean,
1918
componentStack?: string,
@@ -29,10 +28,6 @@ function parseErrorStack(e: ExtendedError): Array<StackFrame> {
2928
? e.stack
3029
: stacktraceParser.parse(e.stack);
3130

32-
let framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
33-
while (framesToPop--) {
34-
stack.shift();
35-
}
3631
return stack;
3732
}
3833

Libraries/Core/ExceptionsManager.js

-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ function reportException(e: ExtendedError, isFatal: boolean) {
9393
extraData: {
9494
jsEngine: e.jsEngine,
9595
rawStack: e.stack,
96-
framesPopped: e.framesToPop,
9796
},
9897
});
9998

@@ -169,7 +168,6 @@ function reactConsoleErrorHandler() {
169168
}
170169
const error: ExtendedError = new SyntheticError(str);
171170
error.name = 'console.error';
172-
error.framesToPop = (error.framesToPop || 0) + 1;
173171
reportException(error, /* isFatal */ false);
174172
}
175173
}

Libraries/Core/__tests__/ExceptionsManager-test.js

+17-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict';
1212

1313
const fs = require('fs');
14+
const path = require('path');
1415

1516
const capturedErrorDefaults = {
1617
componentName: 'A',
@@ -87,7 +88,7 @@ describe('ExceptionsManager', () => {
8788
expect(console.error).toBeCalledWith(formattedMessage);
8889
});
8990

90-
test('pops frames off the stack with framesToPop', () => {
91+
test('does not pop frames off the stack with framesToPop', () => {
9192
function createError() {
9293
const error = new Error('Some error happened');
9394
error.framesToPop = 1;
@@ -103,7 +104,7 @@ describe('ExceptionsManager', () => {
103104
expect(nativeReportException.mock.calls.length).toBe(1);
104105
const exceptionData = nativeReportException.mock.calls[0][0];
105106
expect(getLineFromFrame(exceptionData.stack[0])).toBe(
106-
'const error = createError();',
107+
"const error = new Error('Some error happened');",
107108
);
108109
});
109110

@@ -305,9 +306,9 @@ describe('ExceptionsManager', () => {
305306
);
306307
expect(exceptionData.originalMessage).toBe('"Some error happened"');
307308
expect(exceptionData.name).toBe('console.error');
308-
expect(getLineFromFrame(exceptionData.stack[0])).toBe(
309-
'console.error(message);',
310-
);
309+
expect(
310+
getLineFromFrame(getFirstFrameInThisFile(exceptionData.stack)),
311+
).toBe('console.error(message);');
311312
expect(exceptionData.isFatal).toBe(false);
312313
expect(mockError.mock.calls[0]).toEqual([message]);
313314
});
@@ -326,9 +327,9 @@ describe('ExceptionsManager', () => {
326327
'42, true, ["symbol" failed to stringify], {"y":null}',
327328
);
328329
expect(exceptionData.name).toBe('console.error');
329-
expect(getLineFromFrame(exceptionData.stack[0])).toBe(
330-
'console.error(...args);',
331-
);
330+
expect(
331+
getLineFromFrame(getFirstFrameInThisFile(exceptionData.stack)),
332+
).toBe('console.error(...args);');
332333
expect(exceptionData.isFatal).toBe(false);
333334

334335
expect(mockError).toHaveBeenCalledTimes(1);
@@ -367,7 +368,7 @@ describe('ExceptionsManager', () => {
367368
expect(mockError.mock.calls[0]).toEqual([message]);
368369
});
369370

370-
test('pops frames off the stack with framesToPop', () => {
371+
test('does not pop frames off the stack with framesToPop', () => {
371372
function createError() {
372373
const error = new Error('Some error happened');
373374
error.framesToPop = 1;
@@ -380,7 +381,7 @@ describe('ExceptionsManager', () => {
380381
expect(nativeReportException.mock.calls.length).toBe(1);
381382
const exceptionData = nativeReportException.mock.calls[0][0];
382383
expect(getLineFromFrame(exceptionData.stack[0])).toBe(
383-
'const error = createError();',
384+
"const error = new Error('Some error happened');",
384385
);
385386
});
386387
});
@@ -441,7 +442,7 @@ describe('ExceptionsManager', () => {
441442
expect(console.error.mock.calls[0]).toEqual([message]);
442443
});
443444

444-
test('pops frames off the stack with framesToPop', () => {
445+
test('does not pop frames off the stack with framesToPop', () => {
445446
function createError() {
446447
const error = new Error('Some error happened');
447448
error.framesToPop = 1;
@@ -454,7 +455,7 @@ describe('ExceptionsManager', () => {
454455
expect(nativeReportException.mock.calls.length).toBe(1);
455456
const exceptionData = nativeReportException.mock.calls[0][0];
456457
expect(getLineFromFrame(exceptionData.stack[0])).toBe(
457-
'const error = createError();',
458+
"const error = new Error('Some error happened');",
458459
);
459460
});
460461
});
@@ -550,6 +551,10 @@ function getLineFromFrame({lineNumber /* 1-based */, file}) {
550551
return (lines[lineNumber - 1] || '').trim();
551552
}
552553

554+
function getFirstFrameInThisFile(stack) {
555+
return stack.find(({file}) => file.endsWith(path.basename(module.filename)));
556+
}
557+
553558
// Works around a parseErrorStack bug involving `new X` stack frames.
554559
function cleanFileName(file) {
555560
return file.replace(/^.+? \((?=\/)/, '');

0 commit comments

Comments
 (0)