fs: add stacktrace to fs/promises
Sync functions in fs throwed an error with a stacktrace which is helpful for debugging. But functions in fs/promises throwed an error without a stacktrace. This commit adds stacktraces by calling Error.captureStacktrace and re-throwing the error.
Refs: https://github.com/nodejs/node/issues/34817 Fixes: https://github.com/nodejs/node/issues/50160
import fsS from 'node:fs'
fsS.readdirSync('./foo')
/*
node:fs:1515
handleErrorFromBinding(ctx);
^
Error: ENOENT: no such file or directory, scandir './foo'
at Object.readdirSync (node:fs:1515:3)
at file:///mnt/c/users/green/Downloads/foo/index.mjs:6:5
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:328:24)
at async loadESM (node:internal/process/esm_loader:34:7)
at async handleMainPromise (node:internal/modules/run_main:79:12) {
errno: -2,
syscall: 'scandir',
code: 'ENOENT',
path: './foo'
}
Node.js v21.0.0-pre
*/
import fs from 'node:fs/promises'
await fs.readdir('./foo')
/*
---------- Before ----------
node:internal/process/esm_loader:40
internalBinding('errors').triggerUncaughtException(
^
[Error: ENOENT: no such file or directory, scandir './foo'] {
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: './foo'
}
Node.js v21.0.0-pre
---------- After ----------
node:internal/fs/promises:862
const result = await binding.readdir(
^
Error: ENOENT: no such file or directory, scandir './foo'
at async Object.readdir (node:internal/fs/promises:862:18)
at async file:///mnt/c/users/green/Downloads/foo/index.mjs:5:1 {
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: './foo'
}
Node.js v21.0.0-pre
*/
I have some questions.
- Was the stacktrace generation skipped on purpose? For example, in terms of performance. I remember capturing the stacktrace is slow.
- Is there a better way? I guess I can call
Error.captureStackTrace
on C++ land but didn't find the way.