Skip to content
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

fs: add exists to fsPromises #53737

Closed
wants to merge 1 commit into from

Conversation

avivkeller
Copy link
Member

@avivkeller avivkeller commented Jul 5, 2024

This pull request introduces an exists method to fs.promises.

Rationale: The synchronous fs module includes both exists and existsSync methods, which operate simply by calling access and returning true or false based on success (although existsSync does it a bit differently). Given this straightforward approach, it seems logical to also provide this functionality in fs.promises. There are no technical limitations preventing this, so adding this method enhances consistency and convenience.

@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. labels Jul 5, 2024
@avivkeller
Copy link
Member Author

For context, sync fs.exists is:

/**
 * Tests whether or not the given path exists.
 * @param {string | Buffer | URL} path
 * @param {(exists?: boolean) => any} callback
 * @returns {void}
 */
function exists(path, callback) {
  validateFunction(callback, 'cb');

  function suppressedCallback(err) {
    callback(!err);
  }

  try {
    fs.access(path, F_OK, suppressedCallback);
  } catch {
    return callback(false);
  }
}

@avivkeller avivkeller added the semver-minor PRs that contain new features and should be released in the next minor version. label Jul 5, 2024
@avivkeller
Copy link
Member Author

CC @nodejs/fs

@theoludwig
Copy link
Contributor

This has already been discussed several times, and no consensus.
#39960

I'm +1 for this PR, but unfortunately, it is unlikely to be merged.

@avivkeller
Copy link
Member Author

avivkeller commented Jul 5, 2024

This has already been discussed several times, and no consensus.

#39968 (from back in 2021) didn't reach consensus, but it also staled out (as in, there hasn't been activity in multiple years). Therefor, I'm not confident in this, up-to-date PR for a good discussion.

The main argument against this is that it's easy to do in userland, but if you look at fs.exists, that is also easy to do in userland, and yet, Node.js has it in core.

@aduh95
Copy link
Contributor

aduh95 commented Jul 5, 2024

but if you look at fs.exists, that is also easy to do in userland, and yet, Node.js has it in core.

If you look closer, you'll see it's deprecated.

@avivkeller
Copy link
Member Author

If you look closer, you'll see it's deprecated.

🤣 apparently it is, but existsSync is not, so I still think it should be added to the promises API.

Copy link
Contributor

@aduh95 aduh95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are unaddressed concerns from #39960:


* `path` {string|URL} The filepath to check.

Checks whether the given filepath exists.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not correct, the current implementation checks if the current process can access a file at that path.

@avivkeller avivkeller closed this Jul 6, 2024
@avivkeller
Copy link
Member Author

Sorry for the noise. I should've checked multiple issues and past attempts before considering this change.

I now see that excluding this function was a deliberate decision, and maybe it's best if the promises api doesn't have it.

@emmanuel
Copy link

@redyetidev I don't think anyone reading through #39960 would conclude that the exclusion of fs.promises.exists() was a deliberate decision. There was a stalled discussion about different approaches that could balance some concerns raised. The primary concerns raised were two-fold:

  1. fs.exists() returns false when a file/directory exists but the current process doesn't have access
  2. there are potential race conditions fundamental to interpreting the result of this API call

The races in issue are about the Linux kernel and POSIX process concurrency semantics, and therefore cannot be resolved by Node. I.e., an fs.exists() call provides no guarantee that an immediately following fs.read() will succeed.

Neither shortcoming negates the utility of the fs.exists() API.

This API is clearly very widely used in the wild. The Node.js maintainers will continue to face inbound requests about this functionality until the stdlib includes it. We wouldn't be having this discussion years later otherwise. This NPM module should not exist: https://www.npmjs.com/package/fs.promises.exists.

Continuing to omit this API is at best an act of indifference to the Node.js user base. Moreso it feels like paternalism and casual disregard: "you don't know what's best for you."

Why the stiff resistance to doc'ing the limitations and adding the API?

@avivkeller
Copy link
Member Author

Hi! If you feel strongly about this, I suggest opening an issue with these key ideas. Maybe it'll gain some good traction :-). Thanks for your input!

@emmanuel
Copy link

You're welcome! And thank you for trying!

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 the fs subsystem / file system. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants