使用 fs/promises 和 async..await 进行堆栈跟踪

问题描述 投票:0回答:2

我有一个与这个问题类似的问题,并在这个问题中进行了描述。与 async..await 一起使用时,来自

fs/promises
的错误中没有堆栈跟踪,并且无法确定错误发生的位置。

鉴于应用程序:

foo.js

const { bar } = require('./bar');

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


(async () => {
  await foo();
})().catch(console.error);

bar.js

const fs = require('fs/promises');

exports.bar = async function bar() {
  await fs.readFile('some');
}

当它像

node foo.js
一样运行时,这会导致没有堆栈跟踪的错误:

[Error: ENOENT: no such file or directory, open '...\some'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: '...\\some'
}

其中

error.stack
包含'ENOENT:没有这样的文件或目录,打开'...\some'。

当它像

node --stack_trace_limit=100 -r trace foo.js
一样使用
trace
包运行时,就像链接源中建议的那样,这会导致以下堆栈跟踪:

请注意,内部条目呈灰色,可以过滤掉。

这个

node --stack_trace_limit=100 -r trace -r clarify foo.js
trace
clarify
包会产生以下输出:

Error: ENOENT: no such file or directory, open '...\some'
    at ...\foo.js:8:2
    at Object.<anonymous> (...\foo.js:10:3) {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: '...\\some',
  [Symbol(originalCallSite)]: [],
  [Symbol(mutatedCallSite)]: [ CallSite {}, CallSite {} ]
}

问题是所有输出中都没有提到 bar.js

我的目的是提供干净的错误输出,没有内部条目以及错误发生的确切位置,即 bar.js 中的行号。

这个问题有哪些可能的解决方案?

node.js error-handling async-await fs stack-trace
2个回答
4
投票

如此接近:)

编辑: 基于 fs/promise 问题, 这是一个已知问题,可以根据需要解决,如下所示。

此节点 --stack_trace_limit=100 -r trace -r 澄清 foo.js 使用跟踪和澄清包会产生以下输出:

错误:ENOENT:没有这样的文件或目录,打开“...\some” 在... oo.js:8:2 在对象。 (... oo.js:10:3) {
错误号:-4058,
代码:'ENOENT',
系统调用:'打开',
路径:'...\一些',
[符号(originalCallSite)]:[],
[符号(mutatedCallSite)]:[CallSite {},CallSite {}]
}

问题是所有输出中都没有提到bar.js。

除了使用跟踪/澄清之外, 直接在 fs.readFile 调用(bar.js)上尝试/捕获

const fs = require('fs/promises'); exports.bar = async () => { try { await fs.readFile('some'); } catch (e) { console.error(e); } }

$ node --stack_trace_limit=100 -r trace -r clarify foo.js Error: ENOENT: no such file or directory, open 'some' at emitInitNative (node:internal/async_hooks:205:43) at emitInitNative (node:internal/async_hooks:205:43) at emitInitScript (node:internal/async_hooks:495:3) at promiseInitHook (node:internal/async_hooks:325:3) at promiseInitHookWithDestroyTracking (node:internal/async_hooks:329:3) at Object.readFile (node:internal/fs/promises:786:24) at exports.bar (/home/lz/code/stackover/bar.js:6:18) at foo (/home/lz/code/stackover/foo.js:4:11) at /home/lz/code/stackover/foo.js:9:15 at Object.<anonymous> (/home/lz/code/stackover/foo.js:13:3) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:17:47 { errno: -2, code: 'ENOENT', syscall: 'open', path: 'some' }
您也可以尝试同步读取文件。


2
投票
既然问题的根本原因是

fs/promises

 
Error
 设计上没有堆栈,为什么当您需要堆栈详细信息时不抛出自己的堆栈呢?

除此之外,我建议避免使用 Promise 的

catch

 方法,而仅使用 
async/await 构造。

foo.js

const { bar } = require('./bar'); async function foo() { await bar(); } (async function main() { try { await foo(); } catch(e) { console.error(e); } })();

bar.js

const fs = require('fs/promises'); exports.bar = async function bar() { try{ await fs.readFile('some'); } catch(e) { throw new Error(e.message); } };
这给出了以下结果:

Error: ENOENT: no such file or directory, open 'some' at bar (/home/me/test/bar.js:7:11) at async foo (/home/me/test/foo.js:4:3) at async main (/home/me/test/foo.js:9:5)
可能您不需要使用 

trace

 和/或 
clarify
,但当然您仍然可以根据需要自由使用它们来更改堆栈跟踪。

© www.soinside.com 2019 - 2024. All rights reserved.