stack-trace-mapper/server/util/remap.js
2019-02-13 21:26:28 +01:00

85 lines
2.2 KiB
JavaScript

'use strict'
const { SourceMapConsumer } = require('source-map')
module.exports = function stackTraceMapper (stack, map) {
if (!(map instanceof SourceMapConsumer)) {
throw new Error('map is not a consumer')
}
const setups = [
{
// settings for Chrome, Edge and IE (Plus?)
regex: /\s+at(?:\s+([^\s]+))?\s\(?([/a-z0-9:.-]+):([0-9]+):([0-9]+)/,
// regex: /\s+at(?:\s+([^)]+))?\s\(?([/a-z0-9:.-]+):([0-9]+):([0-9]+)/,
skip: 1,
split: /\n?(?= at )/,
},
{
// settings for Firefox and Safari
regex: /([a-zA-Z0-9]*)@(.*):([0-9]+):([0-9]+)/,
skip: 0,
split: /\s+/,
},
]
const setup = setups.find((setup) => {
return setup.regex.test(stack)
})
if (!setup) {
throw new Error('Stack trace is not recognised')
}
const split = stack.trim().split(setup.split)
// TODO whether the error name and similar preludes the stack varies between browsers perhaps we should create one
const pre = split.slice(0, setup.skip)
console.log('split', split)
console.log('pre', pre)
const lines = split.slice(setup.skip).map((source) => {
// TODO handle lines that have not matched
const match = source.match(setup.regex)
if (!match) {
return { source }
}
const [ , fnc, file, line, column ] = match
return { fnc, file, line: parseInt(line), column: parseInt(column), source }
})
const originalLines = lines.map((obj) => {
if (obj.line) {
return map.originalPositionFor({ line: obj.line, column: obj.column })
}
return obj
})
// need to do research as to why, but the original line objects returned
// contain the function call names are shifted one line compared with
// the sourcemapped stack printed in chrome dev tools
const adjustedLines = originalLines.map((obj, index, arr) => {
if (obj.line) {
const prev = arr[index + 1]
obj.name = (prev && prev.name) || undefined
}
return obj
})
return pre.concat(adjustedLines.map(formatLine))
}
function formatLine ({ source, line, column, name = '(unknown)' }) {
if (!line || !column) {
return ` ${source}`
}
return ` at ${name} (${source}:${line}:${column})`
}