| 1 | const ErrorStackParser = require('error-stack-parser');
|
|---|
| 2 | const theme = require('../theme.js');
|
|---|
| 3 | const utils = require('../utils.js');
|
|---|
| 4 |
|
|---|
| 5 | /**
|
|---|
| 6 | * @typedef {Object} RuntimeErrorStackProps
|
|---|
| 7 | * @property {Error} error
|
|---|
| 8 | */
|
|---|
| 9 |
|
|---|
| 10 | /**
|
|---|
| 11 | * A formatter that turns runtime error stacks into highlighted HTML stacks.
|
|---|
| 12 | * @param {Document} document
|
|---|
| 13 | * @param {HTMLElement} root
|
|---|
| 14 | * @param {RuntimeErrorStackProps} props
|
|---|
| 15 | * @returns {void}
|
|---|
| 16 | */
|
|---|
| 17 | function RuntimeErrorStack(document, root, props) {
|
|---|
| 18 | const stackTitle = document.createElement('h4');
|
|---|
| 19 | stackTitle.innerText = 'Call Stack';
|
|---|
| 20 | stackTitle.style.color = '#' + theme.white;
|
|---|
| 21 | stackTitle.style.fontSize = '1.0625rem';
|
|---|
| 22 | stackTitle.style.fontWeight = '500';
|
|---|
| 23 | stackTitle.style.lineHeight = '1.3';
|
|---|
| 24 | stackTitle.style.margin = '0 0 0.5rem';
|
|---|
| 25 |
|
|---|
| 26 | const stackContainer = document.createElement('div');
|
|---|
| 27 | stackContainer.style.fontSize = '0.8125rem';
|
|---|
| 28 | stackContainer.style.lineHeight = '1.3';
|
|---|
| 29 | stackContainer.style.whiteSpace = 'pre-wrap';
|
|---|
| 30 |
|
|---|
| 31 | let errorStacks;
|
|---|
| 32 | try {
|
|---|
| 33 | errorStacks = ErrorStackParser.parse(props.error);
|
|---|
| 34 | } catch (e) {
|
|---|
| 35 | errorStacks = [];
|
|---|
| 36 | stackContainer.innerHTML = 'No stack trace is available for this error!';
|
|---|
| 37 | }
|
|---|
| 38 |
|
|---|
| 39 | for (let i = 0; i < Math.min(errorStacks.length, 10); i += 1) {
|
|---|
| 40 | const currentStack = errorStacks[i];
|
|---|
| 41 |
|
|---|
| 42 | const functionName = document.createElement('code');
|
|---|
| 43 | functionName.innerHTML = ' ' + currentStack.functionName || '(anonymous function)';
|
|---|
| 44 | functionName.style.color = '#' + theme.yellow;
|
|---|
| 45 | functionName.style.fontFamily = [
|
|---|
| 46 | '"Operator Mono SSm"',
|
|---|
| 47 | '"Operator Mono"',
|
|---|
| 48 | '"Fira Code Retina"',
|
|---|
| 49 | '"Fira Code"',
|
|---|
| 50 | '"FiraCode-Retina"',
|
|---|
| 51 | '"Andale Mono"',
|
|---|
| 52 | '"Lucida Console"',
|
|---|
| 53 | 'Menlo',
|
|---|
| 54 | 'Consolas',
|
|---|
| 55 | 'Monaco',
|
|---|
| 56 | 'monospace',
|
|---|
| 57 | ].join(', ');
|
|---|
| 58 |
|
|---|
| 59 | const fileName = document.createElement('div');
|
|---|
| 60 | fileName.innerHTML =
|
|---|
| 61 | '  ' +
|
|---|
| 62 | utils.formatFilename(currentStack.fileName) +
|
|---|
| 63 | ':' +
|
|---|
| 64 | currentStack.lineNumber +
|
|---|
| 65 | ':' +
|
|---|
| 66 | currentStack.columnNumber;
|
|---|
| 67 | fileName.style.color = '#' + theme.white;
|
|---|
| 68 | fileName.style.fontSize = '0.6875rem';
|
|---|
| 69 | fileName.style.marginBottom = '0.25rem';
|
|---|
| 70 |
|
|---|
| 71 | stackContainer.appendChild(functionName);
|
|---|
| 72 | stackContainer.appendChild(fileName);
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | root.appendChild(stackTitle);
|
|---|
| 76 | root.appendChild(stackContainer);
|
|---|
| 77 | }
|
|---|
| 78 |
|
|---|
| 79 | module.exports = RuntimeErrorStack;
|
|---|