-
Notifications
You must be signed in to change notification settings - Fork 43
Description
I am building a React project that is bundled by WebPack. When an exception is thrown, the raw stack trace often looks like the following:
ReferenceError: callbackFunction is not defined
at http://localhost:3001/522.68d4f3e3cf79d336b78d.js:1:5569
at Object.dispatch (http://localhost:3001/788.b05af27c72430df61875.js:2:292711)
at dispatch (<anonymous>:1:55003)
at ne (http://localhost:3001/522.68d4f3e3cf79d336b78d.js:1:300801)
at onClick (http://localhost:3001/522.68d4f3e3cf79d336b78d.js:1:302829)
at Object.We (http://localhost:3000/935.f53f9fbedad155b70cd5.js:2:16171)
at Ke (http://localhost:3000/935.f53f9fbedad155b70cd5.js:2:16325)
at http://localhost:3000/935.f53f9fbedad155b70cd5.js:2:34503
at Pr (http://localhost:3000/935.f53f9fbedad155b70cd5.js:2:34597)
at Nr (http://localhost:3000/935.f53f9fbedad155b70cd5.js:2:35011)
sourcemapped-stacktrace.js has the following RegEx that it uses to determine if it can map a stack frame properly.
if (traceFormat === "chrome") {
regex = /^ +at.+\((.*):([0-9]+):([0-9]+)/;
The regex assumes that the filename will be surrounded by parenthesis. At least for my project that's not always the case -- in the example above, the first and eighth stack frame do not have parenthesis, fail the check, and don't get mapped. I have no idea why stack traces get generated like this, but they tend to be stack frames I really care about. Incidentally, this has all been in Chrome.
I have a workaround where I process the stack trace, detect if a frame doesn't have parenthesis, and if not, add them before calling sourcemapped-stacktrace's mapStackTrace() function. For others who may have hit this problem you may want to take your trace and call bugWorkaroundStackTrace() before calling mapStackTrace().
So far this workaround seems to properly translate all the frames of a stack trace, but ideally it would be nice if the sourcemapped-stacktrace package could be fixed for this.
// The sourcemapped-stacktrace npm package has a bug: It assumes that the minified filename is
// surrounded in parenthesis in each stack frame. That's not always the case. So, parse each
// stack frame to see if it has parenthesis, and if not, add them. At the end, convert the array
// back into a string with \n at the end of each stack frame. Why? Because that's how
// sourcemapped-stacktrace splits the string in order to process each stack frame.
const bugWorkaroundStackTrace = stackTrace => {
let stackTraceArray = stackTrace.split('\n');
const fixedStackFramesWithLineBreaks = stackTraceArray.map(stackFrame => {
stackFrame = bugWorkaroundStackFrame(stackFrame);
return `${stackFrame}\n`;
});
const fixedStackTrace = fixedStackFramesWithLineBreaks.reduce((stackTraceInProgress, currentFrame) => {
return `${stackTraceInProgress}${currentFrame}`;
});
return fixedStackTrace;
};
const bugWorkaroundStackFrame = stackFrame => {
const parenPositionIdentifier = 'at ';
// If the stack frame does not include the minified file name surrounded in parenthesis,
// sourcemapped-stacktrace will not properly parse the stack frame (it's a bug in the library).
// So, add parenthesis.
if (stackFrame.includes(parenPositionIdentifier) && (!stackFrame.includes('(') || !stackFrame.includes(')'))) {
const position = stackFrame.indexOf(parenPositionIdentifier);
if (position > 0) {
const fixedStackFrame = `${stackFrame.slice(0, position + parenPositionIdentifier.length)}(${stackFrame.slice(
position + parenPositionIdentifier.length
)})`;
stackFrame = fixedStackFrame;
}
}
return stackFrame;
};