Error: BAD
─────────────────────────────
at Object.<anonymous> (D:\Trace\lib.js:215:7)
─────────────────────────────
213 » }
214 » */
215 » throw new Error('BAD');
------------^
216 »
217 »
at Module.Module._compile [as _compile] (module.js:556:32)
at Object.Module._extensions..js [as .js] (module.js:565:10)
at Module.Module.load [as load] (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load [as _load] (module.js:424:3)
at Module.Module.require [as require] (module.js:483:17)
at require (internal/module.js:20:19)
────────────────────────────
at Object.<anonymous> (D:\Trace\test.js:9:9)
────────────────────────────
7 »
8 »
9 » var lib = require('./lib.js');
-------------^
10 »
11 »
at Module.Module._compile [as _compile] (module.js:556:32)
Код файла с ошибкой app.js
require('./stacktrace.js')();
require('fs').readFile('./test.js', function () {
throw new Error('BAD');
});
Код файла stacktrace.js
/*
─────────────────────
/path/to/your/code.js
─────────────────────
189 »
190 » function bar (x) {
191 » throw new Error('x: ' + x);
---------------^
192 » }
193 »
194 » foo(bar);
*/
var LINES_BEFORE = 2
, LINES_AFTER = 3
, MAX_COLUMNS = 80
, DEFAULT_INDENT = 4
, GUTTER_CONTENT = ' » '
, ENDASH_CHAR = '-'
, UP_ARROW_CHAR = '^'
, ELLIPSIS_CHAR = '…'
, EMDASH_CHAR = '─'
, ERR_FILE_NOT_EXIST = 'ENOENT'
, DEFAULT_LIBRARY_REGEX = /node_modules/
, OUTPUT_PREFIX = repeatCharacter(' ', DEFAULT_INDENT); // ==> repeatCharacter()
module.exports = function () {
Error.prepareStackTrace = function (error, frames) {
var lines = [];
try {
lines.push(error.toString());
} catch (error) {
try {
lines.push('<error: ' + error + '>');
} catch (e) {
lines.push('<error>');
}
}
frames.forEach(function (frame) {
var line;
try {
line = formatFrame(frame); // ==> formatFrame()
} catch (error) {
try {
line = '<error: ' + error + '>';
} catch (e) {
line = '<error>';
}
}
lines.push(line);
});
return lines.join('\n');
};
};
function formatFrame (frame) {
var line = ''
, underline = ''
, betterLine = ''
, addPrefix = true
, fileLocationAndContext = getFileLocationAndContextFrom(frame) // ==> getFileLocationAndContextFrom()
, fileLocation = fileLocationAndContext.fileLocation
, context = fileLocationAndContext.context
, functionName = frame.getFunctionName()
, methodName = frame.getMethodName()
, isConstructor = frame.isConstructor()
, isMethodCall = !(frame.isToplevel() || isConstructor);
if (isMethodCall) {
line += frame.getTypeName() + '.';
if (functionName) {
line += functionName;
if (methodName && (methodName != functionName)) {
line += ' [as ' + methodName + ']';
}
} else {
line += methodName || '<anonymous>';
}
} else if (isConstructor) {
line += 'new ' + (functionName || '<anonymous>');
} else if (functionName) {
line += functionName;
} else {
line += fileLocation;
addPrefix = false;
}
if (addPrefix) {
line += ' (' + fileLocation + ')';
}
line = 'at ' + line;
if (context) {
underline = OUTPUT_PREFIX + line.replace(/./g, EMDASH_CHAR);
betterLine = line.replace(/./g, EMDASH_CHAR) + '\n' + OUTPUT_PREFIX + [line, underline, context].join('\n');
return OUTPUT_PREFIX + betterLine + '\n';
} else {
return OUTPUT_PREFIX + line;
}
}
function getFileLocationAndContextFrom (frame) {
var fileLocation = ''
, context = null
, fileName
, lineNumber
, columnNumber;
if (frame.isNative()) {
fileLocation = 'native';
} else if (frame.isEval()) {
fileLocation = 'eval at ' + frame.getEvalOrigin();
} else {
fileName = frame.getFileName();
if (fileName) {
fileLocation += fileName;
lineNumber = frame.getLineNumber();
if (lineNumber != null) {
fileLocation += ':' + lineNumber;
columnNumber = frame.getColumnNumber();
if (columnNumber) {
fileLocation += ':' + columnNumber;
}
try {
if (shouldCollapseDirectory(fileName)) { // ==> shouldCollapseDirectory()
context = null;
} else {
context = formatContext(fileName, lineNumber, columnNumber); // ==> formatContext()
}
} catch(error) {
if (error.code === ERR_FILE_NOT_EXIST) {
context = null;
} else {
context = error;
}
}
}
}
}
if (!fileLocation) {
fileLocation = 'unknown source';
}
return {
fileLocation: fileLocation
, context: context
};
}
function shouldCollapseDirectory (fileName) {
return DEFAULT_LIBRARY_REGEX.test(fileName);
}
function formatContext (fileName, lineNumber, columnNumber) {
var code;
try {
code = require('fs').readFileSync(fileName).toString();
} catch(error) {
if (error.code === ERR_FILE_NOT_EXIST) {
throw error;
}
return OUTPUT_PREFIX + error.toString();
}
// Figure out the lines of context before and after
var lines = code.split('\n')
, preLines = lines.slice(lineNumber - LINES_BEFORE - 1, lineNumber)
, postLines = lines.slice(lineNumber, lineNumber + LINES_AFTER);
// Collect formatted versions of all the lines
var formattedLines = []
, maxLineNumber = lineNumber + LINES_AFTER
, currentLineNumber = lineNumber - LINES_BEFORE;
function renderLines (lines) {
while (lines.length) {
formattedLines.push(
formatCodeLine(currentLineNumber, lines.shift(), maxLineNumber) // ==> formatCodeLine()
);
currentLineNumber++;
}
}
renderLines(preLines);
formattedLines.push(formatCodeArrow(currentLineNumber - 1, columnNumber, maxLineNumber)); // ==> formatCodeArrow()
renderLines(postLines);
return OUTPUT_PREFIX + formattedLines.join('\n' + OUTPUT_PREFIX);
}
function formatCodeLine (lineNumber, line, maxLineNumber) {
var pad = maxLineNumber.toString().length - lineNumber.toString().length
, padding = '';
while (pad-- > 0) {
padding += ' ';
}
if (line.length > MAX_COLUMNS) {
line = line.slice(0, MAX_COLUMNS - 1) + ELLIPSIS_CHAR;
}
return padding + lineNumber + GUTTER_CONTENT + line;
}
function formatCodeArrow (lineNumber, columnNumber, maxLineNumber) {
var length = (GUTTER_CONTENT + maxLineNumber).length + columnNumber;
return repeatCharacter(ENDASH_CHAR, length).slice(0, length - 1) + UP_ARROW_CHAR; // ==> repeatCharacter()
}
function repeatCharacter (character, length) {
return new Array(length).join(character) + character;
}
Комментариев нет:
Отправить комментарий