const ErrorStackParser = require('error-stack-parser'); const theme = require('../theme'); const formatFilename = require('../utils/formatFilename'); /** * @typedef {Object} RuntimeErrorStackProps * @property {Error} error */ /** * A formatter that turns runtime error stacks into highlighted HTML stacks. * @param {Document} document * @param {HTMLElement} root * @param {RuntimeErrorStackProps} props * @returns {void} */ function RuntimeErrorStack(document, root, props) { const stackTitle = document.createElement('h4'); stackTitle.innerText = 'Call Stack'; stackTitle.style.color = '#' + theme.white; stackTitle.style.fontSize = '1.0625rem'; stackTitle.style.fontWeight = '500'; stackTitle.style.lineHeight = '1.3'; stackTitle.style.margin = '0 0 0.5rem'; const stackContainer = document.createElement('div'); stackContainer.style.fontSize = '0.8125rem'; stackContainer.style.lineHeight = '1.3'; stackContainer.style.whiteSpace = 'pre-wrap'; let errorStacks; try { errorStacks = ErrorStackParser.parse(props.error); } catch (e) { errorStacks = []; stackContainer.innerHTML = 'No stack trace is available for this error!'; } for (let i = 0; i < Math.min(errorStacks.length, 10); i += 1) { const currentStack = errorStacks[i]; const functionName = document.createElement('code'); functionName.innerHTML = ' ' + currentStack.functionName || '(anonymous function)'; functionName.style.color = '#' + theme.yellow; functionName.style.fontFamily = [ '"Operator Mono SSm"', '"Operator Mono"', '"Fira Code Retina"', '"Fira Code"', '"FiraCode-Retina"', '"Andale Mono"', '"Lucida Console"', 'Menlo', 'Consolas', 'Monaco', 'monospace', ].join(', '); const fileName = document.createElement('div'); fileName.innerHTML = '  ' + formatFilename(currentStack.fileName) + ':' + currentStack.lineNumber + ':' + currentStack.columnNumber; fileName.style.color = '#' + theme.white; fileName.style.fontSize = '0.6875rem'; fileName.style.marginBottom = '0.25rem'; stackContainer.appendChild(functionName); stackContainer.appendChild(fileName); } root.appendChild(stackTitle); root.appendChild(stackContainer); } module.exports = RuntimeErrorStack;