-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
gripe: deprecating fs.exists/existsSync #1592
Comments
That's not quite how it is. See See #114 for more reference. |
Reason being: |
fs.access doesn't seem like a replacement given that it also throws when there are any accessibility checks that fail. I don't want/need to do error handling every time I check for a file's existence. I don't think it's fair to call this a replacement. |
That would be correct. |
OK, close the issue before I can even reply? Awesome! |
Deprecation with this kind of logic/motivation is only going to serve to make this platform less hospitable to people doing things outside of what features core is focused on. I still don't see any reason why thorough documentation isn't an adequate response to any of the concerns that have been mentioned thus far. |
I'm also pretty concerned at the realization that this is how we're treating issues created around valid questions/concerns. Slapping down an open issue within 20 minutes of its creation is pretty hostile. |
Original discussion can be found at nodejs/node-v0.x-archive#8418 & #103 |
The GitHub close issue button is in the same location a cancel button usually is. This isn't uncommon for people to occasionally do. Is the intent not clear since I directly re-opened it? :/ |
If you're concerned about having to do a try-catch everywhere for var fs = require('fs');
function existsSync(filename) {
try {
fs.accessSync(filename);
return true;
} catch(ex) {
return false;
}
}
function exists(filename, cb) {
fs.access(filename, cb);
// or if want exactly the same old API:
//fs.access(function(err) { cb(err ? false : true); });
} |
or why not leave the wrapper the way it is and let me continue to use fs.existsSync? 😸 |
That same thinking can be applied to just adding more and more sugar to core too. There is plenty discussion in the issues I liked above. At minimum, it wasn't particularly perfect, but it wasn't broken either. |
As previously mentioned, the majority use case for |
@Fishrock123 let's discuss how we can make it good enough to leave in. |
Should I create a new issue, or can we discuss the things that need to be improved on this one? |
This has been discussed to death already. Moving to close. |
@bnoordhuis How about if you're tired of discussing this particular issue: don't involve yourself. |
Kind of hard to do when I get 15 new emails in the 30 minutes I'm away from my computer... at any rate, my point is that you're unlikely to bring up anything that hasn't been brought up before. |
@bnoordhuis understandable. Apologies for contributing to your inbox spam. I'll take a look at the source, read up on previous conversations, and see what I can do to help fix this. |
I made a module for this as there's still genuine use-cases for checking if a file exists without reading the file afterwards. |
Btw, what's wrong with |
Just stopping by to say that I agree with the point @emilyrose makes here. It is true that I personally think that it is, in some cases, acceptable for io.js core APIs to offer functionality that emphasizes simplicity and rapid-development over formal conventions. |
@emilyrose the reason it was deprecated is because |
@imyller that sounds like a documentation issue - and a good pull request |
@benjamingr that is true. I do agree that Additionally, one might want a documentation on why you can create full HTTP server implementation with one-liner, while needing many more lines to check if some local file exists ;) |
Well you can't even tell if file exists or not with the I don't see a single reason why such an api should exist in the core.
Don't worry, the entire http2 community is working on it. In a year or so you won't be able to create http server without getting ssl certificates, and it will surely not be a one-liner anymore |
Was just about to open an issue on this. Documentation is unclear about access being a replacement. I think the real issue here is how the not found is communicated. If access/stat are to be used for an existent check, then an exception on not found is too severe. Wouldn't returning that it's not FRWX sufficient? |
|
@andyhu Once again: Just use |
Seems at this point the ask is for an API that does: function doesReallyExistSync(path) {
try { return !fs.accessSync(path, fs.F_OK) } catch (e) { return false }
} TBH I understand wanting such a simple API, but the problem is it's not actually that simple. Take the following example where directory fs.accessSync('./a' + '/b/a'.repeat(60) + '/c', fs.F_OK) Which will result in the following:
Is node also supposed to add the logic of checking for |
I filed PR #7455 to improve the performance of |
@trevnorris Your |
Just for reference I looked up how other languages/runtimes do this: Python 3 (uses # Does a path exist?
# This is false for dangling symbolic links on systems that support them.
def exists(path):
"""Test whether a path exists. Returns False for broken symbolic links"""
try:
os.stat(path)
except OSError:
return False
return True Java (JDK 8) (uses JNIEXPORT jint JNICALL
Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,
jobject file)
{
jint rv = 0;
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
int mode;
if (statMode(path, &mode)) {
int fmt = mode & S_IFMT;
rv = (jint) (java_io_FileSystem_BA_EXISTS
| ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)
| ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));
}
} END_PLATFORM_STRING(env, path);
return rv;
} Perl (uses my %op = (
r => sub { cando($_[0], S_IRUSR, 1) },
w => sub { cando($_[0], S_IWUSR, 1) },
x => sub { cando($_[0], S_IXUSR, 1) },
o => sub { $_[0][4] == $> },
R => sub { cando($_[0], S_IRUSR, 0) },
W => sub { cando($_[0], S_IWUSR, 0) },
X => sub { cando($_[0], S_IXUSR, 0) },
O => sub { $_[0][4] == $< },
e => sub { 1 } <--- exists PHP (uses /* {{{ proto bool file_exists(string filename)
Returns true if filename exists */
FileFunction(PHP_FN(file_exists), FS_EXISTS)
...
case FS_EXISTS:
RETURN_TRUE; Go (uses if _, err := os.Stat("./thefile.ext"); err != nil {
if os.IsNotExist(err) {
// file does not exist
} else {
// other error
}
} Go language approach is the most interesting: they provide standard With exception of Go language, most common method for implementing "file exists" test seems to be just running |
Not exactly. |
For those interested: I've published a userland module https://github.com/imyller/node-fs-exists-nodeback When loaded the module polyfills This may offer solution to those having issues with the |
I think 7b5ffa4 should fix / address this. It undeprecates |
This has been dragged through various long discussions and has been elevated to the CTC multiple times. As noted in #7455 (comment), while this API is still generally considered an anti-pattern, there are still use-cases it is best suited for, such as checking if a git rebase is in progress by looking if ".git/rebase-apply/rebasing" exists. The general consensus is to undeprecate just the sync version, given that the async version still has the "arguments order inconsistency" problem. The consensus at the two last CTC meetings this came up at was also to undeprecate existsSync() but keep exists() deprecated. See: #8242 & #8330 (Description write-up by @Fishrock123) Fixes: #1592 Refs: #4217 Refs: #7455 PR-URL: #8364 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This has been dragged through various long discussions and has been elevated to the CTC multiple times. As noted in #7455 (comment), while this API is still generally considered an anti-pattern, there are still use-cases it is best suited for, such as checking if a git rebase is in progress by looking if ".git/rebase-apply/rebasing" exists. The general consensus is to undeprecate just the sync version, given that the async version still has the "arguments order inconsistency" problem. The consensus at the two last CTC meetings this came up at was also to undeprecate existsSync() but keep exists() deprecated. See: #8242 & #8330 (Description write-up by @Fishrock123) Fixes: #1592 Refs: #4217 Refs: #7455 PR-URL: #8364 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
After noticing in the node docs that fs.exists and fs.existsSync were going to be deprecated, I took at look at the iojs docs to see that it had in fact been.
This is really annoying and seems like it's based out of the assumption that every developer ever is only checking the existence of a file prior to reading/writing in some async context. While I understand the sentiment behind wanting to avoid 'unnecessary abstractions' or race conditions, this is unnecessary.
Whereas I was previously able to handle the checking of a file's existence with a single boolean variable, I'm now given no other option but to either try/catch or make my code async and listen for error events.
This feels like prescriptivism, as I can't think of a single reason why a stern warning of the potential implications and/or examples of caveats to its use wouldn't have sufficed.
Can anyone help me understand why this was necessary (beyond pushing the all-async-all-the-time paradigm (that doesn't always necessarily apply (particularly in the case of synchronous CLI tooling)))?
Or perhaps can I just submit a PR that un-deprecates this perfectly good functionality?
EDIT: I am happy to provide any additional documentation that is deemed necessary.
The text was updated successfully, but these errors were encountered: