Skip to content

fs: restore stack traces of fs/promises readFile and writeFile errors - #66757

Open
vedchaudhari wants to merge 1 commit into
nodejs:mainfrom
vedchaudhari:fs-promises-stack-trace
Open

vedchaudhari wants to merge 1 commit into
nodejs:mainfrom
vedchaudhari:fs-promises-stack-trace

Conversation

@vedchaudhari

Copy link
Copy Markdown
Contributor

Since #65327 and #65489, errors from fs.promises.readFile(), writeFile() and
appendFile() have no stack frames. This affects v26.8.0+ (readFile()) and
v26.9.0+ (writeFile(), appendFile()); v24.x and v22.x aren't affected.

# main
Error: ENOENT: no such file or directory, open '/missing/config.json'

# this PR
Error: ENOENT: no such file or directory, open '/missing/config.json'
    at readFile (node:internal/fs/promises:2301:7)
    at async loadConfig ([eval]:4:3)

The stack was captured from a C++ callback with no JS frames on it. This captures
it after the await instead, like the rest of fs/promises. The success path is
unchanged, and the fs/readfile-promises and fs/writefile-promises benchmarks
show no difference.

Benchmark results
$ node benchmark/compare.js --old ./node-main --new ./node-pr --runs 10 \
    --set duration=1 --filter readfile-promises --filter writefile-promises fs

macOS arm64, 10 runs per binary. p-values are from a Welch's t-test; * marks p < 0.05.

benchmark configuration main (ops/s) this PR (ops/s) change p-value
readfile-promises concurrent=1 len=1024 encoding='' 56,875 57,183 +0.54% 0.49
readfile-promises concurrent=1 len=1024 encoding='utf-8' 57,179 58,407 +2.15% 0.10
readfile-promises concurrent=1 len=16777216 encoding='' 749 743 -0.82% 0.76
readfile-promises concurrent=1 len=16777216 encoding='utf-8' 424 429 +1.24% 0.71
readfile-promises concurrent=1 len=33554432 encoding='' 331 332 +0.58% 0.67
readfile-promises concurrent=1 len=33554432 encoding='utf-8' 175 173 -1.25% 0.62
readfile-promises concurrent=1 len=4194304 encoding='' 3,047 3,056 +0.29% 0.85
readfile-promises concurrent=1 len=4194304 encoding='utf-8' 2,578 2,627 +1.93% 0.62
readfile-promises concurrent=1 len=524288 encoding='' 20,307 20,203 -0.51% 0.80
readfile-promises concurrent=1 len=524288 encoding='utf-8' 17,994 17,918 -0.42% 0.87
readfile-promises concurrent=1 len=8388608 encoding='' 1,593 1,576 -1.05% 0.64
readfile-promises concurrent=1 len=8388608 encoding='utf-8' 1,142 1,139 -0.26% 0.93
readfile-promises concurrent=10 len=1024 encoding='' 184,282 186,444 +1.17% 0.77
readfile-promises concurrent=10 len=1024 encoding='utf-8' 185,096 177,114 -4.31% 0.23
readfile-promises concurrent=10 len=16777216 encoding='' 1,564 1,593 +1.87% 0.44
readfile-promises concurrent=10 len=16777216 encoding='utf-8' 438 437 -0.30% 0.95
readfile-promises concurrent=10 len=33554432 encoding='' 797 802 +0.59% 0.90
readfile-promises concurrent=10 len=33554432 encoding='utf-8' 213 203 -4.79% 0.26
readfile-promises concurrent=10 len=4194304 encoding='' 6,222 6,135 -1.38% 0.32
readfile-promises concurrent=10 len=4194304 encoding='utf-8' 2,104 2,104 +0.01% 1.00
readfile-promises concurrent=10 len=524288 encoding='' 29,102 30,652 +5.32% 0.16
readfile-promises concurrent=10 len=524288 encoding='utf-8' 28,673 27,922 -2.62% 0.63
readfile-promises concurrent=10 len=8388608 encoding='' 2,931 2,857 -2.52% 0.20
readfile-promises concurrent=10 len=8388608 encoding='utf-8' 921 913 -0.93% 0.73
writefile-promises concurrent=1 size=1024 encodingType='asc' 26,216 26,881 +2.54% 0.65
writefile-promises concurrent=1 size=1024 encodingType='buf' 24,924 26,980 +8.25% 0.30
writefile-promises concurrent=1 size=1024 encodingType='utf' 25,694 25,851 +0.61% 0.94
writefile-promises concurrent=1 size=1048576 encodingType='asc' 2,830 2,870 +1.39% 0.78
writefile-promises concurrent=1 size=1048576 encodingType='buf' 2,868 3,067 +6.94% 0.04 *
writefile-promises concurrent=1 size=1048576 encodingType='utf' 2,894 2,879 -0.50% 0.93
writefile-promises concurrent=1 size=2 encodingType='asc' 28,047 27,462 -2.08% 0.60
writefile-promises concurrent=1 size=2 encodingType='buf' 27,610 28,756 +4.15% 0.46
writefile-promises concurrent=1 size=2 encodingType='utf' 29,195 28,797 -1.36% 0.69
writefile-promises concurrent=1 size=65535 encodingType='asc' 21,725 21,700 -0.11% 0.98
writefile-promises concurrent=1 size=65535 encodingType='buf' 22,605 25,022 +10.69% 0.09
writefile-promises concurrent=1 size=65535 encodingType='utf' 19,432 20,483 +5.41% 0.44
writefile-promises concurrent=10 size=1024 encodingType='asc' 28,006 26,607 -5.00% 0.11
writefile-promises concurrent=10 size=1024 encodingType='buf' 26,818 26,754 -0.24% 0.96
writefile-promises concurrent=10 size=1024 encodingType='utf' 27,985 26,590 -4.98% 0.19
writefile-promises concurrent=10 size=1048576 encodingType='asc' 3,049 2,819 -7.52% 0.14
writefile-promises concurrent=10 size=1048576 encodingType='buf' 2,997 2,851 -4.85% 0.43
writefile-promises concurrent=10 size=1048576 encodingType='utf' 2,975 2,940 -1.17% 0.80
writefile-promises concurrent=10 size=2 encodingType='asc' 28,423 27,387 -3.65% 0.14
writefile-promises concurrent=10 size=2 encodingType='buf' 27,868 27,790 -0.28% 0.94
writefile-promises concurrent=10 size=2 encodingType='utf' 27,878 27,841 -0.13% 0.98
writefile-promises concurrent=10 size=65535 encodingType='asc' 24,832 23,330 -6.05% 0.24
writefile-promises concurrent=10 size=65535 encodingType='buf' 24,651 25,360 +2.88% 0.62
writefile-promises concurrent=10 size=65535 encodingType='utf' 22,357 22,614 +1.15% 0.80

1 of 48 configurations is under p < 0.05, about what chance alone gives with
48 comparisons. It's a 1 MiB write (+6.9%), which is above kWriteFileMaxChunkSize
(512 KiB) and doesn't go through the changed code.

AI-assisted. I reproduced the bug and ran the tests and benchmarks myself.

cc @codebytere

Errors from readFile(), writeFile() and appendFile() have had no stack
frames since they started using a single thread pool round trip, as
the stack was captured from a C++ callback with no JS frames on it.
Capture it after the await instead, like the rest of fs/promises.

Refs: nodejs#65327
Refs: nodejs#65489
Assisted-by: claude:opus-5.5
Signed-off-by: vedchaudhari <vedc2853@gmail.com>
@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to file-system APIs and the fs module. needs-ci PRs that need a full CI run. labels Oct 15, 2026
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.49%. Comparing base (49ad950) to head (6931507).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #66757   +/-   ##
=======================================
  Coverage   90.49%   90.49%           
=======================================
  Files         797      797           
  Lines      277494   277517   +23     
  Branches    53321    53327    +6     
=======================================
+ Hits       251115   251144   +29     
+ Misses      16802    16794    -8     
- Partials     9577     9579    +2     
Files with missing lines Coverage Δ
lib/internal/fs/promises.js 91.27% <100.00%> (+0.13%) ⬆️

... and 36 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vedchaudhari

Copy link
Copy Markdown
Contributor Author

@jasnell since you reviewed #65327 and #65489, would you have a moment to take
a look? It restores the stack traces those round-trip changes dropped for
fs.promises readFile/writeFile errors. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fs Issues and PRs related to file-system APIs and the fs module. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants