{"action":"created","issue":{"url":"https://api.github.com/repos/nodejs/node/issues/4077","labels_url":"https://api.github.com/repos/nodejs/node/issues/4077/labels{/name}","comments_url":"https://api.github.com/repos/nodejs/node/issues/4077/comments","events_url":"https://api.github.com/repos/nodejs/node/issues/4077/events","html_url":"https://github.com/nodejs/node/pull/4077","id":119601626,"number":4077,"title":"fs: un-deprecate existsSync(), throw error on EPERM","user":{"login":"Fishrock123","id":1093990,"avatar_url":"https://avatars.githubusercontent.com/u/1093990?v=3","gravatar_id":"","url":"https://api.github.com/users/Fishrock123","html_url":"https://github.com/Fishrock123","followers_url":"https://api.github.com/users/Fishrock123/followers","following_url":"https://api.github.com/users/Fishrock123/following{/other_user}","gists_url":"https://api.github.com/users/Fishrock123/gists{/gist_id}","starred_url":"https://api.github.com/users/Fishrock123/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fishrock123/subscriptions","organizations_url":"https://api.github.com/users/Fishrock123/orgs","repos_url":"https://api.github.com/users/Fishrock123/repos","events_url":"https://api.github.com/users/Fishrock123/events{/privacy}","received_events_url":"https://api.github.com/users/Fishrock123/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/nodejs/node/labels/discuss","name":"discuss","color":"02d7e1"},{"url":"https://api.github.com/repos/nodejs/node/labels/fs","name":"fs","color":"0052cc"},{"url":"https://api.github.com/repos/nodejs/node/labels/semver-major","name":"semver-major","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":40,"created_at":"2015-11-30T23:03:55Z","updated_at":"2015-12-10T21:34:09Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/nodejs/node/pulls/4077","html_url":"https://github.com/nodejs/node/pull/4077","diff_url":"https://github.com/nodejs/node/pull/4077.diff","patch_url":"https://github.com/nodejs/node/pull/4077.patch"},"body":"This is my conclusion from https://github.com/nodejs/node/issues/1592#issuecomment-159143911.\r\n\r\nA significant amount of people find specifically `existsSync()` useful (especially in simple CLI apps) and it seems unreasonable to require a module for this. Keep `exists()` deprecated as it breaks our errback API convention.\r\n\r\nThis commit makes `existsSync()` throw on `EPERM`. The technical problem with `existsSync()` (besides a race condition if used badly) is that you cannot know if a file does or doesn't exist under Windows with improper permissions.\r\nThrowing in that case really isn't that bad of an idea, since the regular output will probably cause errors anyways down the line, and I don't think these errors can be remedied from Node.js. Instead, error so the end user can clean up their file permissions. Catching this error in user code isn't really worthwhile due to these reasons, so suggest against it.\r\n\r\nDiscuss. cc @nodejs/collaborators "},"comment":{"url":"https://api.github.com/repos/nodejs/node/issues/comments/163755905","html_url":"https://github.com/nodejs/node/pull/4077#issuecomment-163755905","issue_url":"https://api.github.com/repos/nodejs/node/issues/4077","id":163755905,"user":{"login":"trevnorris","id":289174,"avatar_url":"https://avatars.githubusercontent.com/u/289174?v=3","gravatar_id":"","url":"https://api.github.com/users/trevnorris","html_url":"https://github.com/trevnorris","followers_url":"https://api.github.com/users/trevnorris/followers","following_url":"https://api.github.com/users/trevnorris/following{/other_user}","gists_url":"https://api.github.com/users/trevnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/trevnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trevnorris/subscriptions","organizations_url":"https://api.github.com/users/trevnorris/orgs","repos_url":"https://api.github.com/users/trevnorris/repos","events_url":"https://api.github.com/users/trevnorris/events{/privacy}","received_events_url":"https://api.github.com/users/trevnorris/received_events","type":"User","site_admin":false},"created_at":"2015-12-10T21:34:09Z","updated_at":"2015-12-10T21:34:09Z","body":"> The \"other\" core dev position\r\n\r\nWe don't always agree. ;-)\r\n\r\n> I don't understand all these protectionist positions. Bad developers will write bad code\r\n\r\nMy position isn't about that. It's that the API itself is fundamentally flawed. The point of `existsSync()` is to prevent needing to wrap the call in a try/catch. That's literally all the call does. So if there is _any_ case where `existsSync()` can throw then the whole point of it is defeated.\r\n\r\n> If I just want to know if the file exists\r\n\r\nThe point I'm trying to make is a file \"just existing\" is ambiguous. Leading to one reason why `EPERM` would need to be thrown. Knowning whether the file is \"accessible\" is better defined, and more easily determined.\r\n\r\n> (Which you still have to try/catch.)\r\n\r\nThen what does it matter? `existsSync()` is a `statSync()` wrapped in a try/catch. That's literally it. So replacing the call doesn't change anything else in your code.\r\n\r\n> I have no intention of saddling some future maintainer with an ugly comment that says...\r\n\r\nThe documentation states:\r\n\r\n> `fs.F_OK` - File is visible to the calling process. This is useful for determining **if a file exists**, but says nothing about rwx permissions.\r\n\r\nSo it achieves for all intents and purposes the same thing but is better defined. With the added bonus of being more performant."}}