我有点惊讶,自己竟然没有遇到过这种情况。但是,在另一个tick中执行的回调函数中创建的node错误将不会有一个清晰的堆栈跟踪。
例如:
function base (cb) {
process.nextTick(() => {
throw new Error("I am unhelpful")
}, 1000)
}
function top (cb) {
base(cb)
}
top(() => {})
结果为:
Error: I am unhelpful
at /Users/me/stacktrace.js:45:11
at _combinedTickCallback (internal/process/next_tick.js:135:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
at Function.Module.runMain (module.js:607:11)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
当例外发生在执行异步操作的库中的回调/承诺时,特别糟糕,因为没有易于返回追踪以找到问题代码的路径。想象一下涉及控制器、一些辅助模块和第三方库的服务调用。
我的解决方案是在当前刻创建潜在失败情况的错误,然后如果有错误,将其通过:
function base (cb) {
let potentialError = new Error('oh noes')
process.nextTick((err) => {
potentialError.message = err.message
throw potentialError
}, 1000)
}
这个可以给我一个包含调用链的堆栈跟踪:
Error: oh noes
at base (/Users/me/stacktrace.js:47:24)
at top (/Users/me/stacktrace.js:43:3)
at Object.<anonymous> (/Users/me/stacktrace.js:53:1)
我知道像superstack这样的模块,但它们会进行猴子补丁(error monkey patch),并且似乎无法与较新版本的node一起使用。
核心本身只是在异步堆栈跟踪(async stack traces)中内置了支持,但这是一个实验性/开发人员专用功能,不建议在生产环境中使用。
是否有更好的方法来实现我的需求?
http
,它在这里使用了nextTick
here。无论异步模式如何包装调用,堆栈跟踪仍然丢失:\ - Nick Tomlin