假设我有:
const req = require('net').createConnection(80, 'localhost');
req.on('error', (error) => {
console.error(error) // handle somehow
});
如果发生错误事件,我会得到
{ Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 80 }
在终端机上。
我想查看完整的堆栈:
{ Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
at Object.<anonymous> (/Users/aleksey/error-handing-example.js:2:7)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 80 }
注意:我是这样人工获得完整跟踪的:
Error.captureStackTrace(this);
const req = require('net').createConnection(80, 'localhost');
req.on('error', (error) => {
error.stack += this.stack.replace(/^.+$/, '');
console.error(error) // handle somehow
});
我不能为所有错误执行此操作,因为这是不可持续的
有没有办法做到这一点:
答案 0 :(得分:0)
这是我使用async_hooks
并覆盖Error.captureStackTrace
编写的骇人听闻的东西:
const ah = require('async_hooks');
const traces = new Map();
ah.createHook({
init(id) {
const _trace = {};
Error.captureStackTrace(_trace);
traces.set(id, _trace.stack.replace(/(^.+$\n){4}/m, '\n'));
},
destroy(id) {
traces.delete(id);
},
}).enable();
global.Error = class extends Error {
constructor(message) {
super(message);
this.constructor.captureStackTrace(this, this.constructor);
}
static captureStackTrace(what, where) {
super.captureStackTrace.call(Error, what, where);
const trace = traces.get(ah.executionAsyncId());
if (trace) what.stack += trace;
}
};
要点是:
Error.captureStackTrace
以在原始堆栈顶部使用来自该asyncId的跟踪不确定其性能限制,错误和鲁棒性,但这就是我能想到的全部内容。
现在,如果我有:
const req = net.createConnection(8080);
req.once('error', err => {
console.error(err);
});
代替
{ Error: connect ECONNREFUSED 127.0.0.1:8080
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1084:14)
我明白了
{ Error: connect ECONNREFUSED 127.0.0.1:8080
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1084:14)
at TCPConnectWrap.emitInitNative (internal/async_hooks.js:137:43)
at internalConnect (net.js:840:26)
at defaultTriggerAsyncIdScope (internal/async_hooks.js:294:19)
at GetAddrInfoReqWrap.emitLookup [as callback] (net.js:1006:9)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:62:10)
at GetAddrInfoReqWrap.emitInitNative (internal/async_hooks.js:137:43)
at lookup (dns.js:142:19)
at net.js:981:5
at defaultTriggerAsyncIdScope (internal/async_hooks.js:294:19)
at lookupAndConnect (net.js:980:3)
at Socket.connect (net.js:915:5)
at Object.connect (net.js:162:17)
at Object.<anonymous> (/Users/aleksey/epudos-lite/server/test.js:28:17)