节点 - 如何重建完整的堆栈跟踪以进行承诺拒绝

发布于 2025-02-09 05:40:15 字数 2025 浏览 2 评论 0原文

我偶然发现了一个类似于”这个问题,但似乎并不相同。一段时间后,我有一个函数返回承诺并拒绝(如果发生错误)(正在执行HTTP调用,所以需要一些时间)。当请求围绕Internet节点飞行时,请处理其他说明,但是当收到请求并从processTickSandRepontions开始时,堆栈跟踪开始时(我猜是任何异步操作)。这是一个问题 因此,我尝试了以下方法,正常的代码是

const fetch = require('node-fetch');

function myFunction() {
  return new Promise(async (resolve, reject) => {
    fetch('https://www.google.com').then(() => {
      return reject(new Error('Whoops!'));
    });
  });
}

myFunction().catch(console.log);

打印出的

Error: Whoops!
    at /home/dami/projects/testing/stack.js:8:21
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

想法是将旧的堆栈跟踪串联,

function myFunction() {
  const stack = (new Error()).stack;

  return new Promise(async (resolve, reject) => {
    fetch('https://www.google.com').then(() => {
      const error = new Error('Test');
      error.stack += stack;
      reject(error);
    });
  });
}

myFunction().catch(console.log);

Error: Test
    at /home/dami/projects/testing/stack.js:8:21
    at processTicksAndRejections (internal/process/task_queues.js:95:5)Error
    at myFunction (/home/dami/projects/testing/stack.js:4:18)
    at a (/home/dami/projects/testing/stack.js:16:3)
    at Object.<anonymous> (/home/dami/projects/testing/stack.js:19:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47

它似乎并不是我对我的最好(而且最整洁)的解决方案,因为此时我已经有了跟踪的两个“源”(一个是run_main_module上的普通节点过程,另一个是processTickSandlejections)。
因此,最后一个问题是,这个问题有最佳的实践方法吗?我已经尝试使用异步/等待 的最高级别,但由于其异步性质,它将始终通过processTickSandRections拾取。谢谢!

I've stumbled upon an issue similar to the one discussed in this question but does not seem to be the same. I have a function returning a promise and rejecting (in case of errors) after a while (it's doing an HTTP call, so it takes some time). While the request is flying around the internet Node takes care of other instructions, when the request is received and the error thrown the stack trace begins from processTicksAndRejections (as it would for any async operations, I guess). This is a problem as I no longer have a record of where the function was called from.
So I tried the following approach, the normal code would be

const fetch = require('node-fetch');

function myFunction() {
  return new Promise(async (resolve, reject) => {
    fetch('https://www.google.com').then(() => {
      return reject(new Error('Whoops!'));
    });
  });
}

myFunction().catch(console.log);

which prints out

Error: Whoops!
    at /home/dami/projects/testing/stack.js:8:21
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

The idea is to concatenate the old stack trace like

function myFunction() {
  const stack = (new Error()).stack;

  return new Promise(async (resolve, reject) => {
    fetch('https://www.google.com').then(() => {
      const error = new Error('Test');
      error.stack += stack;
      reject(error);
    });
  });
}

myFunction().catch(console.log);

which prints

Error: Test
    at /home/dami/projects/testing/stack.js:8:21
    at processTicksAndRejections (internal/process/task_queues.js:95:5)Error
    at myFunction (/home/dami/projects/testing/stack.js:4:18)
    at a (/home/dami/projects/testing/stack.js:16:3)
    at Object.<anonymous> (/home/dami/projects/testing/stack.js:19:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47

However, this does not seem the best (and most neat) solution to me, as at this point I have two 'sources' of the trace (one being the normal Node process at run_main_module, the other at processTicksAndRejections).
So the final question, is there a best practice approach to this problem? I've tried using async/await and keeping the rejection at the top level of myFunction, but it will always be picked up by processTicksAndRejections because of its async nature. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一杯敬自由 2025-02-16 05:40:15

我将在此处使用异步函数,以保留堆栈跟踪:

async function myFunction() {
    await fetch('https://www.google.com');
    throw new Error('Whoops!');
}

async function foo() {
    await myFunction();
}

async function bar() {
    await foo();
}


bar().catch(console.log);

不要被process.processticksandrejoctions stack Trace中的条目所困扰。只要始终使用异步/等待,应在例外记录整个呼叫链。

I would use an async function here exactly for the reason of preserving the stack trace:

async function myFunction() {
    await fetch('https://www.google.com');
    throw new Error('Whoops!');
}

async function foo() {
    await myFunction();
}

async function bar() {
    await foo();
}


bar().catch(console.log);

Don't be bothered by the process.processTicksAndRejections entry in the stack trace. As long as async/await are used consistently, the whole call chain should be logged with the exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文