-
Notifications
You must be signed in to change notification settings - Fork 18k
os: ReadDir on regular file returns ERROR_PATH_NOT_FOUND instead of ENOTDIR #46734
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
Comments
specifically, in windows isdir is only valid if the file was opened as a directory, which isn't the case when there was a file there https://github.com/golang/go/blob/master/src/os/file_windows.go#L102 |
cc @alexbrainman @bcmills @zx2c4 @mattn @dmitshur re incomplete triage |
That is not enough to reproduce this issue. @codefromthecrypt can you, please, provide complete program with steps to reproduce? Thank you. Alex |
Reading the line below indicates that ENOTDIR is already returned. Lines 14 to 15 in 2ebe77a
This error could be checked with like recommended since #41122 was closed. documentation of
If walking the directory is the issue, then fs.Walkdir was added in It seems that there is nothing left to do for this issue. |
@iwdgo the comments you made rely on file.isdir working. Specifically, check the notes here, which are that file.isdir is the problem #46734 (comment) |
Here's the unit test, and on windows GitHub actions runner, it fails like this, but only on windows (doesn't fail on linux or macOS). Feel free too do whatever you want, just I owed a unit test from earlier. If you think this is ok, just close the issue.
|
@codefromthecrypt Thanks. The provided test fails too on Line 102 in 91e7821
|
Using
|
I think the investigation so far feels like someone trying hard to prove the current code is correct, but wholly missing that the overall experience isn't consistent. I would suggest another person take a look even if they also think the experience is ok to sacrifice and that the result should be telling people one by one that they shouldn't call |
To put it concretely, I believe it is an experience fail to wrap errors only on windows for the same operation. Consistency is important and reduces time loss. It is true someone can say the user is wrong, but there is probably also some value in being direct and consistent in core APIs including error depth. I think this is the key issue and if someone else also thinks through this and decides it is better to close it anyway, go for it, just I would like consistency to be considered. that alone could make the efforts here worth something above zero. |
This sounds like a real bug to me. Windows returns ERROR_PATH_NOT_FOUND in some cases and ERROR_FILE_NOT_FOUND in others. It seems like there's one case of ERROR_PATH_NOT_FOUND that we should be catching and turning into an ENOTDIR? If so, do you know where in the stack that check might be missing? Alternatively, should we be updating a os.IsASomething function to check for ERROR_PATH_NOT_FOUND? In which case, do you know off hand which one? |
The question seems broader than ReadDir(). It is true that the provided code behaves differently on windows and *ix as Go playground shows: https://go.dev/play/p/GM8_PX2CezK The error mapping for windows is here: go/src/syscall/syscall_windows.go Lines 155 to 159 in 6178d25
And for unix, go/src/syscall/syscall_unix.go Lines 133 to 134 in 6178d25
AFAIK, The mapping of errors from windows to Go API is: go/src/syscall/zerrors_windows.go Lines 8 to 9 in 6178d25
A solution is to remove |
I'm not sure that works, though, because I'm pretty sure you get PATH_NOT_FOUND if you try to open "path/notexist/file", but you get FILE_NOT_FOUND if you try to open "path/dir/notexist". In both cases, there, ErrNotExist is the correct interpretation of results. |
Mapping |
I've just ran into this: I am calling I agree with @bcmills and @zx2c4 that we can't simply change how
Which is fine on its own, except for the fact that Also FYI, I think |
* Converted some test data to using filepath.Join() * GCS paths no longer assert using filepath.Join() * REPL tests for file paths assert on the error to avoid os output differences, see: golang/go#46734 PiperOrigin-RevId: 646274646
* Converted some test data to using filepath.Join() * GCS paths no longer assert using filepath.Join() * REPL tests for file paths assert on the error to avoid os output differences, see: golang/go#46734 PiperOrigin-RevId: 646520963
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
err should be ENOTDIR
What did you see instead?
os.IsNotExist(err) matches because it was ERROR_PATH_NOT_FOUND
The text was updated successfully, but these errors were encountered: