我有一个与这个问题类似的问题,并在这个问题中进行了描述。与 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 中的行号。
这个问题有哪些可能的解决方案?
如此接近:)
编辑: 基于 fs/promise 问题, 这是一个已知问题,可以根据需要解决,如下所示。
除了使用跟踪/澄清之外, 直接在 fs.readFile 调用(bar.js)上尝试/捕获此节点 --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。
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'
}
您也可以尝试同步读取文件。
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
,但当然您仍然可以根据需要自由使用它们来更改堆栈跟踪。