fix(ext/node): wrap process.chdir errors with path/dest/syscall#33584
Open
nathanwhitbot wants to merge 4 commits intodenoland:mainfrom
Open
fix(ext/node): wrap process.chdir errors with path/dest/syscall#33584nathanwhitbot wants to merge 4 commits intodenoland:mainfrom
nathanwhitbot wants to merge 4 commits intodenoland:mainfrom
Conversation
Node's `process.chdir` raises a `uv_chdir`-style Error with `code: 'ENOENT'`, `syscall: 'chdir'`, `path` (the cwd before the call), and `dest` (the target). Deno was passing through Deno's `NotFound` error verbatim, so consumers saw `name: 'NotFound'`, no `path`, no `dest`, and a non-uv-shaped message. Snapshot the cwd before the call and run the result through `denoErrorToNodeError` with the expected uv context. Enables `parallel/test-process-chdir-errormessage.js`.
nathanwhitbot
commented
Apr 27, 2026
Contributor
Author
nathanwhitbot
left a comment
There was a problem hiding this comment.
Faithful shape — denoErrorToNodeError → uvException produces an error
that matches Node's binding.chdir error: code: 'ENOENT', path (cwd
before the call), dest (target), syscall: 'chdir', and the
ENOENT: no such file or directory, chdir '<path>' -> '<dest>' message.
A few small things to consider, none blocking:
fs.cwd()failure not wrapped. If the current cwd has been deleted
(e.g.,process.chdirafterrmdir($PWD)), the snapshot call itself
throws and the resulting error skips the wrap. Node's behavior in that
scenario is also odd (uv_cwd fails first), so probably fine — just
flagging that this isn't strictly equivalent.- Errors that don't carry an extractable os errno in their message
flow throughdenoErrorToNodeErrorand come back unchanged, losing the
path/dest/syscallannotations. For the common chdir failure modes
(NotFound → "os error 2", AccessDenied → "os error 13") this works,
but worth keeping in mind if a non-uv-shaped error ever gets thrown
fromfs.chdir. - The test the PR enables (
test-process-chdir-errormessage.js) is
exactly the regression test for this — it asserts onerr.path,
err.dest, and the message format. Good coverage match.
LGTM.
When the current working directory has been deleted (common in tmpdir cleanup during process exit), fs.cwd() throws NotFound. The new process.chdir wrapper from this PR was reading cwd unconditionally before the chdir attempt, propagating that throw as an uncaught NotFound and breaking test-fs-mkdir.js (which exercises the tmpdir cleanup path). Wrap the cwd snapshot in try/catch and fall back to an empty path so the chdir attempt still runs and any failure is shaped through denoErrorToNodeError as before.
The snapshot build at libs/core/extensions.rs:139 enforces 7-bit ASCII on ext:deno_node/* files. The comments I added in 7677cb0 used em dashes which broke the snapshot build on linux-aarch64.
The wrapper now emits a Node-shaped uv error (Error with code, syscall, path, dest) instead of Deno.errors.NotFound. Update the existing 'process.chdir failure' test to assert that shape.
Contributor
Author
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Node's
process.chdirsurfaces a uv-shaped Error with:name: 'Error',code: 'ENOENT'message: ENOENT: no such file or directory, chdir '<oldcwd>' -> '<dest>'path: <cwd before the call>,dest: <argument>,syscall: 'chdir'Deno's polyfill called
Deno.cwd().chdir()and rethrew the rawDeno.errors.NotFound, so callers sawname: 'NotFound', nopath, nodest, and a non-uv message — anything that doestry/catchand checkserr.pathorerr.syscall(a common Node pattern) was broken.This patch snapshots the cwd before the call and runs failures through
denoErrorToNodeError({ syscall: 'chdir', path: fromPath, dest: directory }), matching the C++ binding wrapper used in Node'sinternal/bootstrap/switches/does_own_process_state.js.Enables
parallel/test-process-chdir-errormessage.js.Test plan
cargo test --test node_compat -- test-process-chdir-errormessage(was failing on main, passes here)cargo build --bin denocleantools/format.jsandtools/lint.js --jscleantest-process-chdir,test-process-config.