如何在Node.JS异步函数中保持堆栈跟踪

lf3rwulv  于 2022-12-12  发布在  Node.js
关注(0)|答案(1)|浏览(180)

我有一个异步函数,我从我的路由器处理程序调用:

export const makeHttpRequest = (...) => 
  externalLib(...).catch(err => {throw new Error(JSON.stringify(err))})

externalLib抛出一个JSON(不是Error),因此我将其 Package 在catch子句中,以将其转换为Error类型。
然后在我的路由器处理程序中,我调用这个函数:

const myHandler = (req, res) => {
  ...
  await makeHttpRequest(...)
}

...

app.use(myErrorHandler)

myErrorHandler是记录错误的Express错误处理程序。
但是当我收到来自makeHttpRequest的错误时,stacktrace只显示makeHttpRequest堆栈,而没有路由器跟踪。
为什么会这样?如何添加堆栈跟踪?

gg58donl

gg58donl1#

无关紧要漫谈:* 我在使用node-postgres(又名npm包pg)时也遇到了同样的问题。它似乎超出了客户端的范围,无法跟踪。它也完全按照您所描述的那样--将常规对象作为“错误”传递,而不是Error或只是抛出。我终于找到了一种可靠的方法来处理这个问题,但它不是很漂亮。*
当定义makeHttpRequest时,立即保存当前的stack,然后在函数中(在catch中),你可以记录这个错误。
使用代码的示例:

export const makeHttpRequest = (requestData) => {
  // tracking origin as soon as request begins
  // no callbacks or promises involved yet
  const _stack = new Error().stack;

  return externalLib(requestData)
    .catch(err => {
      // I don't know enough about your code so I'm just adding what I do + what your original did.
      // Play with it if needed
      console.log(`error occurred - origin stack: ${_stack}`);
      throw new Error(JSON.stringify(err));
    });
}

请注意-如果您让这个异步代码在更多嵌套的异步代码中运行(再往下-回调地狱,承诺炼狱),您将由于相同的原因继续遇到这个问题(回调从其他地方、在不同的时间、在不同的堆栈上被触发-不知道将自己添加到队列的堆栈)。

如果你有大量的嵌套路由和/或连续的中间件,你可能还想调整栈显示的多少。把这个放在函数的顶部:

Error.stackTraceLimit = 40;
// or ...
// Error.stackTraceLimit = 3;
// or ...
// Error.stackTraceLimit = Infinity;
// etc.

如果你更喜欢--stack-trace-limit=...,这里还有一个Node标志。这两个标志对于执行上下文都是全局的(Node -每个进程,Chrome -每个窗口/iframe)。更多信息在这里:https://v8.dev/docs/stack-trace-api

相关问题