in packages/bun-error/markdown.ts [31:182]
function exceptionToMarkdown(exception: JSException): string {
const { name: name_, message: message_, stack } = exception;
var name = String(name_).trim();
var message = String(message_).trim();
// check both so if it turns out one of them was only whitespace, we don't count it
const hasName = name_ && name_.length > 0 && name.length > 0;
const hasMessage = message_ && message_.length > 0 && message.length > 0;
let markdown = "";
if (
(name === "Error" ||
name === "RangeError" ||
name === "TypeError" ||
name === "ReferenceError" ||
name === "DOMException") &&
hasMessage
) {
markdown += `**${message}**\n`;
} else if (hasName && hasMessage) {
markdown += `**${name}**\n${message}\n`;
} else if (hasMessage) {
markdown += `${message}\n`;
} else if (hasName) {
markdown += `**${name}**\n`;
}
if (stack.frames.length > 0) {
var frames = stack.frames;
if (stack.source_lines.length > 0) {
const {
file: _file = "",
function_name = "",
position: { line = -1, column_start: column = -1, column_stop: columnEnd = column } = {
line: -1,
column_start: -1,
column_stop: -1,
},
scope = 0 as any,
} = stack.frames[0];
const file = normalizedFilename(_file, thisCwd);
if (file) {
if (function_name.length > 0) {
markdown += `In \`${function_name}\` – ${file}`;
} else if (scope > 0 && scope < StackFrameScope.Constructor + 1) {
markdown += `${StackFrameIdentifier({
functionName: function_name,
scope,
markdown: true,
})} ${file}`;
} else {
markdown += `In ${file}`;
}
if (line > -1) {
markdown += `:${line}`;
if (column > -1) {
markdown += `:${column}`;
}
}
if (stack.source_lines.length > 0) {
// TODO: include loader
const extnameI = file.lastIndexOf(".");
const extname = extnameI > -1 ? file.slice(extnameI + 1) : "";
markdown += "\n```";
markdown += extname;
markdown += "\n";
stack.source_lines.forEach(sourceLine => {
const lineText = sourceLine.text.trimEnd();
markdown += lineText + "\n";
if (sourceLine.line === line && stack.source_lines.length > 1) {
// the comment should start at the first non-whitespace character
// ideally it should be length the original line
// but it may not be
var prefix = "".padStart(lineText.length - lineText.trimStart().length, " ");
prefix += "/* ".padEnd(column - 1 - prefix.length, " ") + "^ happened here ";
markdown += prefix.padEnd(Math.max(lineText.length, 1) - 1, " ") + "*/\n";
}
});
markdown = markdown.trimEnd() + "\n```";
}
}
}
if (frames.length > 0) {
markdown += "\nStack trace:\n";
var padding = 0;
// Limit to 8 frames because it may be a huge stack trace
// and we want to not hit the message limit
const framesToDisplay = frames.slice(0, Math.min(frames.length, 8));
for (let frame of framesToDisplay) {
const {
function_name = "",
position: { line = -1, column_start: column = -1 } = {
line: -1,
column_start: -1,
},
scope = 0 as any,
} = frame;
padding = Math.max(
padding,
StackFrameIdentifier({
scope,
functionName: function_name,
markdown: true,
}).length,
);
}
markdown += "```js\n";
for (let frame of framesToDisplay) {
const {
file = "",
function_name = "",
position: { line = -1, column_start: column = -1 } = {
line: -1,
column_start: -1,
},
scope = 0 as any,
} = frame;
markdown += `
${StackFrameIdentifier({
scope,
functionName: function_name,
markdown: true,
}).padEnd(padding, " ")}`;
if (file) {
markdown += ` ${normalizedFilename(file, thisCwd)}`;
if (line > -1) {
markdown += `:${line}`;
if (column > -1) {
markdown += `:${column}`;
}
}
}
}
markdown += "\n```\n";
}
}
return markdown;
}