Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for parsing hermes-style stack traces #2406

Merged
merged 3 commits into from
Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/browser/src/tracekit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface StackTrace {
const UNKNOWN_FUNCTION = '?';

// Chromium based browsers: Chrome, Brave, new Opera, new Edge
const chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
const chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
// We need this specific case for now because we want no other regex to match.
Expand Down Expand Up @@ -113,7 +113,9 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {
parts[4] = submatch[3]; // column
}
element = {
url: parts[2],
// working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `
// prefix here seems like the quickest solution for now.
url: parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2],
func: parts[1] || UNKNOWN_FUNCTION,
args: isNative ? [parts[2]] : [],
line: parts[3] ? +parts[3] : null,
Expand Down
21 changes: 21 additions & 0 deletions packages/browser/test/unit/tracekit/original.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { computeStackTrace } from '../../../src/tracekit';

import {
ANDROID_REACT_NATIVE,
ANDROID_REACT_NATIVE_HERMES,
ANDROID_REACT_NATIVE_PROD,
CHROME_15,
CHROME_36,
Expand Down Expand Up @@ -922,4 +923,24 @@ describe('Tracekit - Original Tests', () => {
column: null,
});
});

it('should parse React Native errors on Android Hermes', () => {
const stackFrames = computeStackTrace(ANDROID_REACT_NATIVE_HERMES);
expect(stackFrames).to.be.ok;
expect(stackFrames.stack.length).to.equal(26);
expect(stackFrames.stack[0]).to.deep.equal({
url: 'index.android.bundle',
func: 'onPress',
args: [],
line: 1,
column: 452701,
});
expect(stackFrames.stack[3]).to.deep.equal({
url: 'native',
func: '_receiveSignal',
args: ['native'],
line: null,
column: null,
});
});
});
32 changes: 32 additions & 0 deletions packages/browser/test/unit/tracekit/originalfixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,35 @@ export const ANDROID_REACT_NATIVE_PROD = {
'value@index.android.bundle:29:927\n' +
'[native code]',
};

export const ANDROID_REACT_NATIVE_HERMES = {
message: 'Error: lets throw!',
name: 'Error',
stack:
'at onPress (address at index.android.bundle:1:452701)\n' +
'at anonymous (address at index.android.bundle:1:224280)\n' +
'at _performSideEffectsForTransition (address at index.android.bundle:1:230843)\n' +
'at _receiveSignal (native)\n' +
'at touchableHandleResponderRelease (native)\n' +
'at onResponderRelease (native)\n' +
'at apply (native)\n' +
'at b (address at index.android.bundle:1:74037)\n' +
'at apply (native)\n' +
'at k (address at index.android.bundle:1:74094)\n' +
'at apply (native)\n' +
'at C (address at index.android.bundle:1:74126)\n' +
'at N (address at index.android.bundle:1:74267)\n' +
'at A (address at index.android.bundle:1:74709)\n' +
'at forEach (native)\n' +
'at z (address at index.android.bundle:1:74642)\n' +
'at anonymous (address at index.android.bundle:1:77747)\n' +
'at _e (address at index.android.bundle:1:127755)\n' +
'at Ne (address at index.android.bundle:1:77238)\n' +
'at Ue (address at index.android.bundle:1:77571)\n' +
'at receiveTouches (address at index.android.bundle:1:122512)\n' +
'at apply (native)\n' +
'at value (address at index.android.bundle:1:33176)\n' +
'at anonymous (address at index.android.bundle:1:31603)\n' +
'at value (address at index.android.bundle:1:32776)\n' +
'at value (address at index.android.bundle:1:31561)',
};