Skip to content

fix(process): improve error message for process.cwd() when directory is deleted #57184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,16 @@ added:

An attempt to invoke an unsupported crypto operation was made.

<a id="ERR_CWD_DELETED"></a>

### `ERR_CWD_DELETED`

<!-- YAML
added: REPLACEME
-->

The current working directory has been deleted during the process' lifetime.

<a id="ERR_DEBUGGER_ERROR"></a>

### `ERR_DEBUGGER_ERROR`
Expand Down
5 changes: 5 additions & 0 deletions src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details);

#define ERRORS_WITH_CODE(V) \
V(ERR_ACCESS_DENIED, Error) \
V(ERR_CWD_DELETED, Error) \
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, Error) \
V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError) \
V(ERR_BUFFER_TOO_LARGE, Error) \
Expand Down Expand Up @@ -170,6 +171,10 @@ ERRORS_WITH_CODE(V)

#define PREDEFINED_ERROR_MESSAGES(V) \
V(ERR_ACCESS_DENIED, "Access to this API has been restricted") \
V(ERR_CWD_DELETED, \
"Current working directory does not exist. " \
"It may have been deleted while the process was still " \
"inside it. Use process.chdir() to change to a valid directory.") \
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, \
"Buffer is not available for the current Context") \
V(ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort") \
Expand Down
4 changes: 4 additions & 0 deletions src/node_process_methods.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ static void Cwd(const FunctionCallbackInfo<Value>& args) {
char buf[PATH_MAX_BYTES];
size_t cwd_len = sizeof(buf);
int err = uv_cwd(buf, &cwd_len);
if (err == UV_ENOENT) {
THROW_ERR_CWD_DELETED(env);
return;
}
if (err) {
return env->ThrowUVException(err, "uv_cwd");
}
Expand Down
43 changes: 43 additions & 0 deletions test/parallel/test-process-cwd-deleted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

// This test verifies that an appropriate error is thrown when the current
// working directory is deleted and process.cwd() is called.
//
// We do this by spawning a forked process and deleting the tmp cwd
// while it is starting up.

const common = require('../common');
const { fork } = require('node:child_process');
const { rmSync } = require('node:fs');
const assert = require('node:assert'); // Import assert properly
const { Buffer } = require('node:buffer');

if (process.argv[2] === 'child') {
try {
while (true) {
process.cwd(); // Continuously call process.cwd()
}
} catch (err) {
console.error(err);
process.exit(1); // Ensure the process exits with failure
}
}

const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
const tmpDir = tmpdir.path;

const proc = fork(__filename, ['child'], {
cwd: tmpDir,
silent: true,
});

proc.on('spawn', common.mustCall(() => rmSync(tmpDir, { recursive: true })));

proc.on('exit', common.mustCall((code) => {
assert.strictEqual(code, 1);
proc.stderr.toArray().then(common.mustCall((chunks) => {
const buf = Buffer.concat(chunks);
assert.match(buf.toString(), /Current working directory does not exist/);
}));
}));