Skip to content

Commit 549947b

Browse files
authored
feat: Add support for parsing hermes-style stack traces (getsentry#2406)
* feat: Add support for parsing hermes-style stack traces * make linters happy * actually test with a real react-native stack
1 parent a51d701 commit 549947b

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

packages/browser/src/tracekit.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export interface StackTrace {
4242
const UNKNOWN_FUNCTION = '?';
4343

4444
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
45-
const chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
45+
const chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
4646
// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
4747
// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
4848
// We need this specific case for now because we want no other regex to match.
@@ -113,7 +113,9 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {
113113
parts[4] = submatch[3]; // column
114114
}
115115
element = {
116-
url: parts[2],
116+
// working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `
117+
// prefix here seems like the quickest solution for now.
118+
url: parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2],
117119
func: parts[1] || UNKNOWN_FUNCTION,
118120
args: isNative ? [parts[2]] : [],
119121
line: parts[3] ? +parts[3] : null,

packages/browser/test/unit/tracekit/original.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { computeStackTrace } from '../../../src/tracekit';
88

99
import {
1010
ANDROID_REACT_NATIVE,
11+
ANDROID_REACT_NATIVE_HERMES,
1112
ANDROID_REACT_NATIVE_PROD,
1213
CHROME_15,
1314
CHROME_36,
@@ -922,4 +923,24 @@ describe('Tracekit - Original Tests', () => {
922923
column: null,
923924
});
924925
});
926+
927+
it('should parse React Native errors on Android Hermes', () => {
928+
const stackFrames = computeStackTrace(ANDROID_REACT_NATIVE_HERMES);
929+
expect(stackFrames).to.be.ok;
930+
expect(stackFrames.stack.length).to.equal(26);
931+
expect(stackFrames.stack[0]).to.deep.equal({
932+
url: 'index.android.bundle',
933+
func: 'onPress',
934+
args: [],
935+
line: 1,
936+
column: 452701,
937+
});
938+
expect(stackFrames.stack[3]).to.deep.equal({
939+
url: 'native',
940+
func: '_receiveSignal',
941+
args: ['native'],
942+
line: null,
943+
column: null,
944+
});
945+
});
925946
});

packages/browser/test/unit/tracekit/originalfixtures.ts

+32
Original file line numberDiff line numberDiff line change
@@ -482,3 +482,35 @@ export const ANDROID_REACT_NATIVE_PROD = {
482482
'value@index.android.bundle:29:927\n' +
483483
'[native code]',
484484
};
485+
486+
export const ANDROID_REACT_NATIVE_HERMES = {
487+
message: 'Error: lets throw!',
488+
name: 'Error',
489+
stack:
490+
'at onPress (address at index.android.bundle:1:452701)\n' +
491+
'at anonymous (address at index.android.bundle:1:224280)\n' +
492+
'at _performSideEffectsForTransition (address at index.android.bundle:1:230843)\n' +
493+
'at _receiveSignal (native)\n' +
494+
'at touchableHandleResponderRelease (native)\n' +
495+
'at onResponderRelease (native)\n' +
496+
'at apply (native)\n' +
497+
'at b (address at index.android.bundle:1:74037)\n' +
498+
'at apply (native)\n' +
499+
'at k (address at index.android.bundle:1:74094)\n' +
500+
'at apply (native)\n' +
501+
'at C (address at index.android.bundle:1:74126)\n' +
502+
'at N (address at index.android.bundle:1:74267)\n' +
503+
'at A (address at index.android.bundle:1:74709)\n' +
504+
'at forEach (native)\n' +
505+
'at z (address at index.android.bundle:1:74642)\n' +
506+
'at anonymous (address at index.android.bundle:1:77747)\n' +
507+
'at _e (address at index.android.bundle:1:127755)\n' +
508+
'at Ne (address at index.android.bundle:1:77238)\n' +
509+
'at Ue (address at index.android.bundle:1:77571)\n' +
510+
'at receiveTouches (address at index.android.bundle:1:122512)\n' +
511+
'at apply (native)\n' +
512+
'at value (address at index.android.bundle:1:33176)\n' +
513+
'at anonymous (address at index.android.bundle:1:31603)\n' +
514+
'at value (address at index.android.bundle:1:32776)\n' +
515+
'at value (address at index.android.bundle:1:31561)',
516+
};

0 commit comments

Comments
 (0)