-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
Somehow support checking if a path exists while using fs.promises #39960
Comments
async function exists(f) {
try {
await fs.promises.stat(f);
return true;
} catch {
return false;
}
} 😄 |
Alternatively, you can use |
I think it makes sense to implement |
Historically, that might be true, but > fs.existsSync('/root/snap') // existing directory but no permission
false If we really want to keep using a misleading name, the documentation should be very clear that |
Instead of keeping the misleading name, I'd prefer we implement the promise version correctly: return a boolean if we know for sure whether the file exists or not, throw in other cases. |
I tend to agree, but that's inconsistent with the existing APIs. And I have a feeling that most use cases won't handle that third case ( |
I'm not sure I understand. Is your opinion that people should use |
I don't have a clear preference. The sync version makes a very weak statement: whether some file system entry is visible to the process right now. It doesn't make any statement about the type of the file system entry nor about permissions nor about the entry's existence during the processes' next CPU cycle. I have a suspicion that the mere existence of However, there are surely some valid use cases that truly only care about the existence right now and about nothing else. I don't have a strong opinion. Either throw, which is inconsistent with the other
|
The key challenge with |
@ctjlewis Let me remind you of our Code of Conduct that includes "Being respectful of differing opinions" as a community standard. We neither support rude comments nor expressions that are generally considered rude or offensive. I did acknowledge that there are some use cases that would benefit from Convenience is a valid concern when designing APIs. However, personally, I believe that correctness, safety, security, and consistency are similarly if not more important, and should be considered :) (Edit: original comment deleted by author.) |
honestly looking at this issue, it sounds like we should honestly consider removing |
Expanding on the problem a bit, providing a nicer handler for people to use that does what |
Maybe a better response would be "use |
I don't know. My use cases for For example: if (!exists('node_modules')) {
run('npm install');
}
run(exists('package-lock.json') ? 'npm ci' : 'npm install'); |
Perhaps a better approach would be something more like...
Where the given callback is invoked immediately if the path exists. This type of pattern would avoid the race condition that exists in the current API. |
It's system-level race condition. Another process or thread can delete file or change its permissions. Though, API with signature like |
@jasnell that would solve it, although it definitely feels like an API departure in a way that I'd hope we'd be able to avoid. |
Only for the current thread, though. A worker thread or a different process could delete or create the file in the meantime. Personally, I don't think the race condition is the main problem. Applications that use My main concern is #39960 (comment): the sync version never throws and misleadingly tells users that a file does not exist when it really just cannot be accessed. An async implementation as in #39968 could either keep that misleading behavior or throw when the existence of the file cannot be determined, but that would then require proper error handling etc., which might not be much simpler than when using |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment. For more information on how the project manages feature requests, please consult the feature request management document. |
This issue should be still considered. |
Sounds like a good semver major change :) |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
I'll put this out to pasture, the discussion here is a little too unfocused. My understanding of reading it:
|
If I may, I'd like to ask that we reopen this. As I understand it, there are two concerns with the
The first is "just a bug". (Air-quotes on that so as not to appear too dismissive. I know "small" API issues like this are hard to deal with in a project of this size.) That can/should be dealt with on it's own merits. For example, I'd suggest leaving the Where the race-condition issue is concerned, import fs from 'node:fs/promises';
async function work() {
return fs.writeFile('test.txt', 'hello world').then(() => fs.unlink('test.txt')).then(work);
}
work(), work(); ... will very quickly throw "ENOENT: no such file or directory".) The rhetorical question being: "Why be okay with race conditions resulting from async The problem with not providing an async
My long-winded point here is that lack of |
I created new pull-request with API change: |
@ohhmm It isn't accidentally omitted feature from If you want to get it implemented, I suggest reading these comments: #39960 (comment) |
@Ginden, there is no way to remove this kind of race condition, except transaction file systems. |
If someone want to have secure solution without race conditions then transactions may be emulated by creating file watcher, to monitor if file deleted. This way |
If
|
Don’t forget the classic |
Thanks. Indeed this works. It means you need to create a wrapper function to return boolean value. It's fine for a simple script, but if it is a real application, such function will be placed in util. I don't see much necessary to maintain the complexity. New node versions has already droped legacy OS support. By adding returning a |
Is your feature request related to a problem? Please describe.
Presently,
fs.exists
is deprecated andfs.existsSync
is only available if you're not usingpromises
. The exists check is absolutely useful, and it would be really useful to have it available in thefs.promises
API.Describe the solution you'd like
fs.promises,exists
orfs.promises.existsSync
should work.Describe alternatives you've considered
The text was updated successfully, but these errors were encountered: