mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Filter out Hermes internal bytecode frames from error stack traces
Summary: Changelog: [Fixed][General] Filter out Hermes internal bytecode frames (Promise implementation) from error stack traces Currently, React Native strips native frames from call stacks reported via ExceptionsManager / LogBox. This diff does the same for *internal bytecode* frames in Hermes, which are functionally similar to native frames: they are implementation details of the engine for which source code isn't readily available. In particular this change will avoid confusing symbolication tools that may otherwise try to treat `InternalBytecode.js` frames as belonging to the main React Native bundle (and produce garbage output). Reviewed By: GijsWeterings Differential Revision: D42367135 fbshipit-source-id: b7904f10c7ff6956e7b736b575dde1ce45028200
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f723ab002e
commit
4c911a2dec
@@ -52,6 +52,44 @@ describe('parseHermesStack', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
test('internal bytecode location', () => {
|
||||
expect(
|
||||
parseHermesStack(
|
||||
[
|
||||
'TypeError: undefined is not a function',
|
||||
' at internal (address at InternalBytecode.js:1:9)',
|
||||
' at notInternal (address at /js/InternalBytecode.js:10:1234)',
|
||||
].join('\n'),
|
||||
),
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"entries": Array [
|
||||
Object {
|
||||
"functionName": "internal",
|
||||
"location": Object {
|
||||
"line1Based": 1,
|
||||
"sourceUrl": "InternalBytecode.js",
|
||||
"type": "INTERNAL_BYTECODE",
|
||||
"virtualOffset0Based": 9,
|
||||
},
|
||||
"type": "FRAME",
|
||||
},
|
||||
Object {
|
||||
"functionName": "notInternal",
|
||||
"location": Object {
|
||||
"line1Based": 10,
|
||||
"sourceUrl": "/js/InternalBytecode.js",
|
||||
"type": "BYTECODE",
|
||||
"virtualOffset0Based": 1234,
|
||||
},
|
||||
"type": "FRAME",
|
||||
},
|
||||
],
|
||||
"message": "TypeError: undefined is not a function",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('source location', () => {
|
||||
expect(
|
||||
parseHermesStack(
|
||||
|
||||
@@ -22,7 +22,7 @@ function convertHermesStack(stack: HermesParsedStack): Array<StackFrame> {
|
||||
continue;
|
||||
}
|
||||
const {location, functionName} = entry;
|
||||
if (location.type === 'NATIVE') {
|
||||
if (location.type === 'NATIVE' || location.type === 'INTERNAL_BYTECODE') {
|
||||
continue;
|
||||
}
|
||||
frames.push({
|
||||
|
||||
@@ -21,6 +21,13 @@ type HermesStackLocationSource = $ReadOnly<{
|
||||
column1Based: number,
|
||||
}>;
|
||||
|
||||
type HermesStackLocationInternalBytecode = $ReadOnly<{
|
||||
type: 'INTERNAL_BYTECODE',
|
||||
sourceUrl: string,
|
||||
line1Based: number,
|
||||
virtualOffset0Based: number,
|
||||
}>;
|
||||
|
||||
type HermesStackLocationBytecode = $ReadOnly<{
|
||||
type: 'BYTECODE',
|
||||
sourceUrl: string,
|
||||
@@ -31,6 +38,7 @@ type HermesStackLocationBytecode = $ReadOnly<{
|
||||
type HermesStackLocation =
|
||||
| HermesStackLocationNative
|
||||
| HermesStackLocationSource
|
||||
| HermesStackLocationInternalBytecode
|
||||
| HermesStackLocationBytecode;
|
||||
|
||||
type HermesStackEntryFrame = $ReadOnly<{
|
||||
@@ -65,6 +73,11 @@ const RE_FRAME =
|
||||
// 1. count of skipped frames
|
||||
const RE_SKIPPED = /^ {4}... skipping (\d+) frames$/;
|
||||
|
||||
function isInternalBytecodeSourceUrl(sourceUrl: string): boolean {
|
||||
// See https://github.com/facebook/hermes/blob/3332fa020cae0bab751f648db7c94e1d687eeec7/lib/VM/Runtime.cpp#L1100
|
||||
return sourceUrl === 'InternalBytecode.js';
|
||||
}
|
||||
|
||||
function parseLine(line: string): ?HermesStackEntry {
|
||||
const asFrame = line.match(RE_FRAME);
|
||||
if (asFrame) {
|
||||
@@ -75,12 +88,19 @@ function parseLine(line: string): ?HermesStackEntry {
|
||||
asFrame[2] === 'native'
|
||||
? {type: 'NATIVE'}
|
||||
: asFrame[3] === 'address at '
|
||||
? {
|
||||
type: 'BYTECODE',
|
||||
sourceUrl: asFrame[4],
|
||||
line1Based: Number.parseInt(asFrame[5], 10),
|
||||
virtualOffset0Based: Number.parseInt(asFrame[6], 10),
|
||||
}
|
||||
? isInternalBytecodeSourceUrl(asFrame[4])
|
||||
? {
|
||||
type: 'INTERNAL_BYTECODE',
|
||||
sourceUrl: asFrame[4],
|
||||
line1Based: Number.parseInt(asFrame[5], 10),
|
||||
virtualOffset0Based: Number.parseInt(asFrame[6], 10),
|
||||
}
|
||||
: {
|
||||
type: 'BYTECODE',
|
||||
sourceUrl: asFrame[4],
|
||||
line1Based: Number.parseInt(asFrame[5], 10),
|
||||
virtualOffset0Based: Number.parseInt(asFrame[6], 10),
|
||||
}
|
||||
: {
|
||||
type: 'SOURCE',
|
||||
sourceUrl: asFrame[4],
|
||||
|
||||
Reference in New Issue
Block a user