improve error source maps

This commit is contained in:
Pooya Parsa 2018-01-05 12:49:32 +03:30
parent 36ee372b0b
commit 05a7595701

View File

@ -1,6 +1,5 @@
const Youch = require('@nuxtjs/youch') const Youch = require('@nuxtjs/youch')
const { SourceMapConsumer } = require('source-map') const { join, resolve, relative, isAbsolute } = require('path')
const { join, resolve } = require('path')
const { readFile } = require('fs-extra') const { readFile } = require('fs-extra')
module.exports = function errorMiddleware(err, req, res, next) { module.exports = function errorMiddleware(err, req, res, next) {
@ -56,81 +55,39 @@ module.exports = function errorMiddleware(err, req, res, next) {
} }
async function readSource(frame) { async function readSource(frame) {
const serverBundle = this.resources.serverBundle
// Remove webpack:/// & query string from the end // Remove webpack:/// & query string from the end
const sanitizeName = name => name ? name.replace('webpack:///', '').split('?')[0] : '' const sanitizeName = name => name ? name.replace('webpack:///', '').split('?')[0] : null
// SourceMap Support for SSR Bundle
if (serverBundle && serverBundle.maps[frame.fileName]) {
// Initialize smc cache
if (!serverBundle.$maps) {
serverBundle.$maps = {}
}
// Read SourceMap object
const smc = serverBundle.$maps[frame.fileName] || new SourceMapConsumer(serverBundle.maps[frame.fileName])
serverBundle.$maps[frame.fileName] = smc
// Try to find original position
const { line, column, name, source } = smc.originalPositionFor({
line: frame.getLineNumber() || 0,
column: frame.getColumnNumber() || 0,
bias: SourceMapConsumer.LEAST_UPPER_BOUND
})
if (line) {
frame.lineNumber = line
}
/* istanbul ignore if */
if (column) {
frame.columnNumber = column
}
/* istanbul ignore if */
if (name) {
frame.functionName = name
}
if (source) {
frame.fileName = sanitizeName(source)
// Source detected, try to get original source code
const contents = smc.sourceContentFor(source)
if (contents) {
frame.contents = contents
}
}
}
// Return if fileName is still unknown
if (!frame.fileName) {
return
}
frame.fileName = sanitizeName(frame.fileName) frame.fileName = sanitizeName(frame.fileName)
// Try to read from SSR bundle files // Return if fileName is unknown
if (serverBundle && serverBundle.files[frame.fileName]) { if (!frame.fileName) {
frame.contents = serverBundle.files[frame.fileName]
return return
} }
// Possible paths for file // Possible paths for file
const searchPath = [ const searchPath = [
this.options.srcDir,
this.options.rootDir, this.options.rootDir,
join(this.options.buildDir, 'dist'), join(this.options.buildDir, 'dist'),
this.options.srcDir,
this.options.buildDir this.options.buildDir
] ]
// Scan filesystem for real path // Scan filesystem for real source
for (let pathDir of searchPath) { for (let pathDir of searchPath) {
let fullPath = resolve(pathDir, frame.fileName) let fullPath = resolve(pathDir, frame.fileName)
let source = await readFile(fullPath, 'utf-8').catch(() => null) let source = await readFile(fullPath, 'utf-8').catch(() => null)
if (source) { if (source) {
if (!frame.contents) {
frame.contents = source frame.contents = source
}
frame.fullPath = fullPath frame.fullPath = fullPath
if (isAbsolute(frame.fileName)) {
frame.fileName = relative(this.options.rootDir, fullPath)
}
return return
} }
} }
// Fallback: use server bundle
if (!frame.contents) {
frame.contents = this.resources.serverBundle.files[frame.fileName]
}
} }