【问题标题】:Async stacktraces in node节点中的异步堆栈跟踪
【发布时间】:2018-02-21 10:17:14
【问题描述】:

我有点惊讶我没有被这个更多的困扰,但是在另一个滴答中执行的回调中创建的节点错误没有一个健全的堆栈跟踪。

例如

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 这样的模块,但它们会修补错误并且似乎不适用于最新版本的节点。

核心本身只是内置了对async stack traces 的支持,但这是一个实验性/开发性功能,不建议用于生产。

有没有更好的方法来实现我想要的?

【问题讨论】:

  • 在处理 promise 时,有一个很好的处理方法。但对于一般的异步回调......没有那么多
  • 我认为在我的情况下,违规者实际上是http,它使用nextTick here,无论包装调用的异步模式如何,堆栈跟踪仍然丢失:\
  • 是的,为了在 Promise 中正确抛出它,需要对 nextTick 进行 Promisified。如果你从 .then 中抛出,它将被传递给 .catch。但是如果你从后来创建承诺的东西中抛出,或者从解决承诺的东西中抛出,它不会通过。

标签: node.js asynchronous error-handling


【解决方案1】:

这现在可用于节点 12.x 中的 async 函数(使用 async 关键字的函数,而不是所有异步函数),通过 --async-stack-traces 命令行标志。希望这最终将在所有地方标准化。

更多详情请见release notesfeature document

目前不支持非 async 函数,唉。

【讨论】:

    猜你喜欢
    • 2021-02-25
    • 1970-01-01
    • 2011-01-05
    • 2016-05-29
    • 2017-08-06
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多