Skip to content

Instantly share code, notes, and snippets.

@shitpoet
Created January 17, 2017 04:10
Show Gist options
  • Save shitpoet/f17d79908de78b9f315793e00145ee0c to your computer and use it in GitHub Desktop.
Save shitpoet/f17d79908de78b9f315793e00145ee0c to your computer and use it in GitHub Desktop.
Reimplementation of default uncaught exception handler of nodejs
// reimplementation of default uncaught exception handler of nodejs v7.2 in js
//
// produces the same output as default handler of nodejs
// handles inline source maps with sinlge source (as V8 does)
// does not handle non-inline source maps or maps with multiple sources
//
// [email protected], public domain
"use strict";
let util = require('util')
let Module = require('module')
let fs = require('fs')
let path = require('path')
process.on('uncaughtException', (e) => {
handle_error(e)
});
function parse_stack_line(text) {
let s = text.trim().split(' ').pop()
if (s.startsWith('(')) s = s.slice(1,-1)
let [fn,ln,col] = s.split(':')
return {fn,ln,col}
}
function handle_error(e) {
function output_source_line(fn,ln,col) {
if (fs.existsSync(fn)) {
log('generated file found')
let dcode = fs.readFileSync(fn, 'utf-8')
let cmnt = dcode.split('\n')[0]
let convert = require('convert-source-map')
let sm_json = convert.fromComment(cmnt).toJSON()
const sm = require('source-map')
const smc = new sm.SourceMapConsumer(sm_json)
fn = smc.sources[0]
let pos = smc.originalPositionFor({
line: ln|0, column: col|0
})
ln = pos.line
col = pos.column
}
let dirname = path.dirname(fn)
let cwd = process.cwd()
if (dirname.indexOf(cwd)==0)
dirname = '.' + dirname.substring(cwd.length)
let name = path.basename(fn)
// output file name and position, source line and "^" marker
console.log(dirname+'/\x1b[01;39m'+name+'\x1b[00;39m:'+ln)
console.log(fs.readFileSync(fn,'utf8').split('\n')[ln-1])
console.log(' '.repeat(col) + '^\n')
}
let stack = e.stack
if (typeof stack != typeof void 0) {
let ss = stack.split('\n')
ss = ss.filter( s=>s.trim().startsWith('at '))
let frame = 0 // last frame
let {fn,ln,col} = parse_stack_line(ss[frame])
try {
output_source_line(fn,ln,col)
} catch(e) {
console.error(e)
}
console.log(stack)
} else {
console.error(e)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment