起源
原理
对于 Node 而言,服务器 source map 最大的价值在于错误信息有正确的错误堆栈,所以只要我们能够实现自定义错误堆栈信息就可以了。
function prepareStackTrace(error, stack) {
return error + stack.map(function(frame) {
return '\n at ' + wrapCallSite(frame);;
}).join('');
}
Error.prepareStackTrace = prepareStackTrace;
在 wrapCallSite
方法里面可以通过分析源码,找到 sourceMap 然后返回正确的位置信息。
原理很简单,已经有一个 npm 包 source-map-support 封装好了相关功能。
这看起来已经很完美了。source map 读取只在出现错误的时候才执行,所以**这个功能不会有性能问题,在生成环境也可以开启**。
问题
Stack Trace API 看起来很美好,但现实场景总是更加复杂。我在引入 source-map-support 后,运行起来没什么问题,但在跑测试用例的时候,错误堆栈的位置信息完全不对。
问题定位到后,解决就容易了。但解决这个问题得先讲讲 power-assert 是如何实现的。
power-assert 与 sourceMap
power-assert 作为一个断言库,最大的特色在于错误信息的报告是非常友好的,一张图可以很清晰看到区别
实现这样炫酷的报告是需要做一些特殊的处理,把测试用例的代码进行一次转换,举个例子
it('foo', function foo() {
var a = 'foo';
var b = 'b';
assert(a === b);
});
it('foo', function foo() {
var a = 'foo';
var b = 'b';
assert(expr(capture(capture(a, '/0/left') === capture(b, '/0/right'), '/0'), {
content: 'assert(a === b)',
filepath: 'bizLogger.test.ts',
line: 107
}));
})
我所遇到的问题也就是因为 power-assert 对代码进行了转换,最终异常抛出时,真实 js 异常位置信息是转换后的位置,这个位置自然是无法正确定位到源码位置了。