Created
January 17, 2017 04:10
-
-
Save shitpoet/f17d79908de78b9f315793e00145ee0c to your computer and use it in GitHub Desktop.
Reimplementation of default uncaught exception handler of nodejs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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