Skip to content

Commit 6b57641

Browse files
committed
Allow the parser to mostly work when require is not available
1 parent 2bc3bc9 commit 6b57641

File tree

2 files changed

+73
-74
lines changed

2 files changed

+73
-74
lines changed

packages/node/src/eventbuilder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { node } from './stack-parser';
1616
* Extracts stack frames from the error.stack string
1717
*/
1818
export function extractStackFromError(error: Error): StackFrame[] {
19-
return createStackParser(node)(error.stack || '');
19+
return createStackParser(node(require))(error.stack || '');
2020
}
2121

2222
/**

packages/node/src/stack-parser.ts

+72-73
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import { basename, dirname, StackLineParser } from '@sentry/utils';
22

3-
const mainModule: string = `${
4-
(require.main && require.main.filename && dirname(require.main.filename)) || global.process.cwd()
5-
}/`;
6-
73
/** Gets the module */
8-
function getModule(filename: string | undefined): string | undefined {
9-
if (!filename) {
4+
function getModule(nodeRequire: NodeRequire | undefined, filename: string | undefined): string | undefined {
5+
if (!filename || !nodeRequire) {
106
return;
117
}
128

13-
const base = mainModule;
9+
const base = `${
10+
(nodeRequire.main && nodeRequire.main.filename && dirname(nodeRequire.main.filename)) || global.process.cwd()
11+
}/`;
1412

1513
// It's specifically a module
1614
const file = basename(filename, '.js');
@@ -39,82 +37,83 @@ function getModule(filename: string | undefined): string | undefined {
3937
const FILENAME_MATCH = /^\s*[-]{4,}$/;
4038
const FULL_MATCH = /at (?:(.+?)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;
4139

42-
// eslint-disable-next-line complexity
43-
export const node: StackLineParser = (line: string) => {
44-
if (line.match(FILENAME_MATCH)) {
45-
return {
46-
filename: line,
47-
};
48-
}
40+
export const node = (nodeRequire: NodeRequire | undefined): StackLineParser => {
41+
return (line: string) => {
42+
if (line.match(FILENAME_MATCH)) {
43+
return {
44+
filename: line,
45+
};
46+
}
4947

50-
const lineMatch = line.match(FULL_MATCH);
51-
if (!lineMatch) {
52-
return undefined;
53-
}
48+
const lineMatch = line.match(FULL_MATCH);
49+
if (!lineMatch) {
50+
return undefined;
51+
}
5452

55-
let object: string | undefined;
56-
let method: string | undefined;
57-
let functionName: string | undefined;
58-
let typeName: string | undefined;
59-
let methodName: string | undefined;
53+
let object: string | undefined;
54+
let method: string | undefined;
55+
let functionName: string | undefined;
56+
let typeName: string | undefined;
57+
let methodName: string | undefined;
6058

61-
if (lineMatch[1]) {
62-
functionName = lineMatch[1];
59+
if (lineMatch[1]) {
60+
functionName = lineMatch[1];
6361

64-
let methodStart = functionName.lastIndexOf('.');
65-
if (functionName[methodStart - 1] === '.') {
66-
// eslint-disable-next-line no-plusplus
67-
methodStart--;
68-
}
62+
let methodStart = functionName.lastIndexOf('.');
63+
if (functionName[methodStart - 1] === '.') {
64+
// eslint-disable-next-line no-plusplus
65+
methodStart--;
66+
}
6967

70-
if (methodStart > 0) {
71-
object = functionName.substr(0, methodStart);
72-
method = functionName.substr(methodStart + 1);
73-
const objectEnd = object.indexOf('.Module');
74-
if (objectEnd > 0) {
75-
functionName = functionName.substr(objectEnd + 1);
76-
object = object.substr(0, objectEnd);
68+
if (methodStart > 0) {
69+
object = functionName.substr(0, methodStart);
70+
method = functionName.substr(methodStart + 1);
71+
const objectEnd = object.indexOf('.Module');
72+
if (objectEnd > 0) {
73+
functionName = functionName.substr(objectEnd + 1);
74+
object = object.substr(0, objectEnd);
75+
}
7776
}
77+
typeName = undefined;
7878
}
79-
typeName = undefined;
80-
}
8179

82-
if (method) {
83-
typeName = object;
84-
methodName = method;
85-
}
80+
if (method) {
81+
typeName = object;
82+
methodName = method;
83+
}
8684

87-
if (method === '<anonymous>') {
88-
methodName = undefined;
89-
functionName = undefined;
90-
}
85+
if (method === '<anonymous>') {
86+
methodName = undefined;
87+
functionName = undefined;
88+
}
9189

92-
let fn;
93-
try {
94-
fn = functionName || `${typeName}.${methodName || '<anonymous>'}`;
95-
} catch (_) {
96-
// This seems to happen sometimes when using 'use strict',
97-
// stemming from `getTypeName`.
98-
// [TypeError: Cannot read property 'constructor' of undefined]
99-
fn = '<anonymous>';
100-
}
90+
let fn;
91+
try {
92+
fn = functionName || `${typeName}.${methodName || '<anonymous>'}`;
93+
} catch (_) {
94+
// This seems to happen sometimes when using 'use strict',
95+
// stemming from `getTypeName`.
96+
// [TypeError: Cannot read property 'constructor' of undefined]
97+
fn = '<anonymous>';
98+
}
99+
100+
const filename = lineMatch[2];
101+
const isNative = lineMatch[5] === 'native';
102+
const isInternal =
103+
isNative || (filename && !filename.startsWith('/') && !filename.startsWith('.') && filename.indexOf(':\\') !== 1);
104+
105+
// in_app is all that's not an internal Node function or a module within node_modules
106+
// note that isNative appears to return true even for node core libraries
107+
// see https://github.com/getsentry/raven-node/issues/176
108+
const in_app = !isInternal && filename !== undefined && !filename.includes('node_modules/');
101109

102-
const filename = lineMatch[2];
103-
const isNative = lineMatch[5] === 'native';
104-
const isInternal =
105-
isNative || (filename && !filename.startsWith('/') && !filename.startsWith('.') && filename.indexOf(':\\') !== 1);
106-
107-
// in_app is all that's not an internal Node function or a module within node_modules
108-
// note that isNative appears to return true even for node core libraries
109-
// see https://github.com/getsentry/raven-node/issues/176
110-
const in_app = !isInternal && filename !== undefined && !filename.includes('node_modules/');
111-
112-
return {
113-
filename,
114-
module: getModule(filename),
115-
function: fn,
116-
lineno: parseInt(lineMatch[3], 10) || undefined,
117-
colno: parseInt(lineMatch[4], 10) || undefined,
118-
in_app,
110+
return {
111+
filename,
112+
module: getModule(nodeRequire, filename),
113+
function: fn,
114+
lineno: parseInt(lineMatch[3], 10) || undefined,
115+
colno: parseInt(lineMatch[4], 10) || undefined,
116+
in_app,
117+
};
119118
};
120119
};

0 commit comments

Comments
 (0)