-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Correctly parse mixed chrome/node renderer stack traces (#509)
- Loading branch information
Showing
6 changed files
with
184 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { chromeStackLineParser } from '@sentry/browser'; | ||
import { StackFrame, StackParser } from '@sentry/types'; | ||
import { dropUndefinedKeys, nodeStackLineParser, stripSentryFramesAndReverse } from '@sentry/utils'; | ||
|
||
const [, chrome] = chromeStackLineParser; | ||
const [, node] = nodeStackLineParser(); | ||
|
||
/** | ||
* A stack parser than combines Chrome and node.js parsers to give the best results even when nodeIntegration = true | ||
*/ | ||
export const electronRendererStackParser: StackParser = (stack: string, skipFirst: number = 0): StackFrame[] => { | ||
const frames: StackFrame[] = []; | ||
|
||
for (const line of stack.split('\n').slice(skipFirst)) { | ||
const chromeFrame = chrome(line); | ||
const nodeFrame = node(line); | ||
|
||
// We favour the chrome parser unless in_app == false | ||
if (chromeFrame && nodeFrame?.in_app !== false) { | ||
frames.push(chromeFrame); | ||
} else if (nodeFrame) { | ||
frames.push(dropUndefinedKeys(nodeFrame)); | ||
} | ||
} | ||
|
||
return stripSentryFramesAndReverse(frames); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { expect, should, use } from 'chai'; | ||
import chaiAsPromised = require('chai-as-promised'); | ||
|
||
import { electronRendererStackParser } from '../../src/renderer/stack-parse'; | ||
|
||
should(); | ||
use(chaiAsPromised); | ||
|
||
describe('Parse mixed renderer stack traces', () => { | ||
it('Electron v2', () => { | ||
const stack = `Error: ENOENT: no such file or directory, open '/does-not-exist' | ||
at Object.fs.openSync (fs.js:646:18) | ||
at Object.module.(anonymous function) [as openSync] (ELECTRON_ASAR.js:166:20) | ||
at fs.readFileSync (fs.js:551:33) | ||
at fs.readFileSync (ELECTRON_ASAR.js:538:29) | ||
at two (file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:17:11) | ||
at one (file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:24:9) | ||
at global.setTimeout (file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:28:9) | ||
at sentryWrapped (/Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/node_modules/@sentry/browser/cjs/helpers.js:87:17)`; | ||
|
||
const frames = electronRendererStackParser(stack); | ||
|
||
expect(frames).to.eql([ | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: 'global.setTimeout', | ||
in_app: true, | ||
lineno: 28, | ||
colno: 9, | ||
}, | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: 'one', | ||
in_app: true, | ||
lineno: 24, | ||
colno: 9, | ||
}, | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: 'two', | ||
in_app: true, | ||
lineno: 17, | ||
colno: 11, | ||
}, | ||
{ | ||
filename: 'ELECTRON_ASAR.js', | ||
function: 'fs.readFileSync', | ||
lineno: 538, | ||
colno: 29, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'fs.js', | ||
function: 'fs.readFileSync', | ||
lineno: 551, | ||
colno: 33, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'ELECTRON_ASAR.js', | ||
function: 'Object.module.(anonymous function) [as openSync]', | ||
lineno: 166, | ||
colno: 20, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'fs.js', | ||
function: 'Object.fs.openSync', | ||
lineno: 646, | ||
colno: 18, | ||
in_app: false, | ||
}, | ||
]); | ||
}); | ||
|
||
it('Electron v19', () => { | ||
const stack = `Error: ENOENT: no such file or directory, open '/does-not-exist' | ||
at Object.openSync (node:fs:585:3) | ||
at Object.func [as openSync] (node:electron/js2c/asar_bundle:5:1812) | ||
at readFileSync (node:fs:453:35) | ||
at e.readFileSync (node:electron/js2c/asar_bundle:5:9160) | ||
at two (file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:17:11) | ||
at one (file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:24:9) | ||
at file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html:28:9 | ||
at sentryWrapped (/Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/node_modules/@sentry/browser/cjs/helpers.js:87:17)`; | ||
|
||
const frames = electronRendererStackParser(stack); | ||
|
||
expect(frames).to.eql([ | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: '?', | ||
in_app: true, | ||
lineno: 28, | ||
colno: 9, | ||
}, | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: 'one', | ||
in_app: true, | ||
lineno: 24, | ||
colno: 9, | ||
}, | ||
{ | ||
filename: | ||
'file:///Users/tim/Documents/Repositories/sentry-electron/test/e2e/dist/javascript-renderer/src/index.html', | ||
function: 'two', | ||
in_app: true, | ||
lineno: 17, | ||
colno: 11, | ||
}, | ||
{ | ||
filename: 'node:electron/js2c/asar_bundle', | ||
function: 'e.readFileSync', | ||
lineno: 5, | ||
colno: 9160, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'node:fs', | ||
function: 'readFileSync', | ||
lineno: 453, | ||
colno: 35, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'node:electron/js2c/asar_bundle', | ||
function: 'Object.func [as openSync]', | ||
lineno: 5, | ||
colno: 1812, | ||
in_app: false, | ||
}, | ||
{ | ||
filename: 'node:fs', | ||
function: 'Object.openSync', | ||
lineno: 585, | ||
colno: 3, | ||
in_app: false, | ||
}, | ||
]); | ||
}); | ||
}); |